Decompiled source of Scopophobia v1.3.1
BepInEx/plugins/Scopophobia.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalConfig; using LethalConfig.ConfigItems; using LethalConfig.ConfigItems.Options; using LethalLib; using LethalLib.Modules; using Microsoft.CodeAnalysis; using Scopophobia; using Scopophobia.Data; using Scopophobia.Dependencies; using Scopophobia.NetcodePatcher; using Scopophobia.Patches; using ShyGuy.AI; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.AI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Adds SCP-096 Shy Guy To Lethal Company, Complete with Custom Animations, Sound effects, and more.")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("TheUnknownCod3r")] [assembly: AssemblyDescription("Adds SCP-096 Shy Guy To Lethal Company, Complete with Custom Animations, Sound effects, and more.")] [assembly: AssemblyFileVersion("1.2.8.0")] [assembly: AssemblyInformationalVersion("1.2.8")] [assembly: AssemblyProduct("Scopophobia")] [assembly: AssemblyTitle("Scopophobia")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.2.8.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } [HarmonyPatch(typeof(BeltBagItem))] public static class BeltBagItemPatch { [HarmonyPatch(typeof(BeltBagItem), "PutObjectInBagLocalClient")] [HarmonyPrefix] private static void Prefix_PutObjectInBagLocalClient(BeltBagItem __instance, GrabbableObject gObject) { if (!((Object)(object)gObject == (Object)null)) { ShyGuyPaintingProp component = ((Component)gObject).GetComponent<ShyGuyPaintingProp>(); if ((Object)(object)component != (Object)null && !component.hasSpawned) { PlayerControllerB playerHeldBy = ((GrabbableObject)__instance).playerHeldBy; ScopophobiaPlugin.Instance.LogInfoExtended("[BeltBagPatch] Trigger painting on pickup: " + ((Object)component).name); component.TriggerFromBeltBag(playerHeldBy); } } } } [HarmonyPatch(typeof(RoundManager))] internal static class RoundManagerPatch { [HarmonyPatch("LoadNewLevel")] [HarmonyPostfix] private static void LoadNewLevelPatch() { EnemyDataManager.SetEnemyDataForCurrentLevel(); } } [HarmonyPatch(typeof(StartOfRound))] internal static class StartOfRoundPatch { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPatch() { EnemyDataManager.Initialize(); } } [Serializable] public class SyncedInstance<T> { [NonSerialized] protected static int IntSize = 4; internal static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager; internal static bool IsClient => NetworkManager.Singleton.IsClient; internal static bool IsHost => NetworkManager.Singleton.IsHost; public static T Default { get; private set; } public static T Instance { get; private set; } public static bool Synced { get; internal set; } protected void InitInstance(T instance) { Default = instance; Instance = instance; IntSize = 4; } internal static void SyncInstance(byte[] data) { Instance = DeserializeFromBytes(data); Synced = true; } internal static void RevertSync() { Instance = Default; Synced = false; } public static byte[] SerializeToBytes(T val) { BinaryFormatter binaryFormatter = new BinaryFormatter(); using MemoryStream memoryStream = new MemoryStream(); try { binaryFormatter.Serialize(memoryStream, val); return memoryStream.ToArray(); } catch (Exception arg) { ScopophobiaPlugin.logger.LogError((object)$"Error serializing instance: {arg}"); return null; } } public static T DeserializeFromBytes(byte[] data) { BinaryFormatter binaryFormatter = new BinaryFormatter(); using MemoryStream serializationStream = new MemoryStream(data); try { return (T)binaryFormatter.Deserialize(serializationStream); } catch (Exception arg) { ScopophobiaPlugin.logger.LogError((object)$"Error deserializing instance: {arg}"); return default(T); } } } namespace ShyGuy.AI { public class ShyGuyAI : EnemyAI { private Transform localPlayerCamera; public Vector3 mainEntrancePosition; public Collider mainCollider; public static bool canSeeFace; public VehicleController CompanyCruiser; public bool pryingOpenDoor; public HangarShipDoor shipDoor; private float pryingDoorAnimTime; public float pryOpenDoorAnimLength; public AudioClip breakAndEnter; public AudioClip shipAlarm; public AudioSource breakDownDoorAudio; public AudioSource farAudio; public AudioSource footstepSource; public AudioClip screamSFX; public AudioClip panicSFX; public AudioClip crySFX; public AudioClip crySittingSFX; public AudioClip killPlayerSFX; [Header("Containment Breach Sounds")] public AudioClip screamSFX_CB; public AudioClip panicSFX_CB; public AudioClip crySFX_CB; public AudioClip killPlayerSFX_CB; [Header("Alpha Containment Breach Sounds")] public AudioClip screamSFX_ACB; public AudioClip panicSFX_ACB; public AudioClip crySFX_ACB; public AudioClip killPlayerSFX_ACB; [Header("Secret Laboratory Sounds")] public AudioClip screamSFX_SL; public AudioClip panicSFX_SL; public AudioClip crySFX_SL; public AudioClip killPlayerSFX_SL; private int currentClipID = -1; private NetworkVariable<int> syncedAudioClipID = new NetworkVariable<int>(-1, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0); public Material bloodyMaterial; public AISearchRoutine roamMap; public Transform shyGuyFace; private Vector3 spawnPosition; private Vector3 previousPosition; private int previousState = -1; private float roamWaitTime = 40f; [Header("Teleports")] public static EntranceTeleport[] entranceTeleports; public static List<EntranceTeleport> outsideTeleports = new List<EntranceTeleport>(); public static List<EntranceTeleport> insideTeleports = new List<EntranceTeleport>(); public bool pathingToTeleport; public Vector3 closestTeleportPosition; public static EntranceTeleport mainEntrance; public EntranceTeleport closestTeleport; private bool roamShouldSit; private bool sitting; private float lastRunSpeed; private float seeFaceTime; private float triggerTime; public float triggerDuration = 66.4f; private float timeToTrigger = 0.5f; private float lastInterval; private bool inKillAnimation; private bool isInElevatorStartRoom; private float timeAtLastUsingEntrance; public static MineshaftElevatorController elevatorScript; public List<PlayerControllerB> SCP096Targets = new List<PlayerControllerB>(); public override void Start() { //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown //IL_0327: Unknown result type (might be due to invalid IL or missing references) //IL_032c: Unknown result type (might be due to invalid IL or missing references) //IL_0338: Unknown result type (might be due to invalid IL or missing references) //IL_036b: 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_0378: Unknown result type (might be due to invalid IL or missing references) //IL_0380: Unknown result type (might be due to invalid IL or missing references) //IL_0385: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Expected O, but got Unknown ((EnemyAI)this).Start(); if ((Object)(object)CompanyCruiser == (Object)null) { CompanyCruiser = Object.FindObjectOfType<VehicleController>(); } if ((Object)(object)shipDoor == (Object)null) { shipDoor = Object.FindObjectOfType<HangarShipDoor>(); } if ((Object)(object)base.agent == (Object)null) { base.agent = ((Component)this).GetComponentInChildren<NavMeshAgent>(); } if ((Object)(object)elevatorScript == (Object)null) { elevatorScript = Object.FindObjectOfType<MineshaftElevatorController>(); } triggerDuration = Config.triggerTime; lastInterval = Time.realtimeSinceStartup; Transform val = null; Queue<Transform> queue = new Queue<Transform>(); queue.Enqueue(((Component)this).transform); while (queue.Count > 0) { Transform val2 = queue.Dequeue(); if (((Object)val2).name == "lefteye") { val = val2; break; } foreach (Transform item3 in val2) { Transform item = item3; queue.Enqueue(item); } } Transform val3 = null; queue = new Queue<Transform>(); queue.Enqueue(((Component)this).transform); while (queue.Count > 0) { Transform val4 = queue.Dequeue(); if (((Object)val4).name == "righteye") { val3 = val4; break; } foreach (Transform item4 in val4) { Transform item2 = item4; queue.Enqueue(item2); } } if (!Config.hasGlowingEyes && (Object)(object)val != (Object)null && (Object)(object)val3 != (Object)null) { ((Component)val).gameObject.SetActive(false); ((Component)val3).gameObject.SetActive(false); } if (Config.bloodyTexture && (Object)(object)bloodyMaterial != (Object)null) { Transform val5 = ((Component)this).transform.Find("SCP096Model"); if ((Object)(object)val5 != (Object)null) { Transform val6 = val5.Find("tsg_placeholder"); if ((Object)(object)val6 != (Object)null) { SkinnedMeshRenderer component = ((Component)val6).GetComponent<SkinnedMeshRenderer>(); if ((Object)(object)component != (Object)null) { ((Renderer)component).material = bloodyMaterial; } } } } switch (Config.soundPack) { case "SCPCB": screamSFX = screamSFX_CB; crySFX = crySFX_CB; crySittingSFX = crySFX_CB; panicSFX = panicSFX_CB; killPlayerSFX = killPlayerSFX_CB; break; case "SCPCBOld": screamSFX = screamSFX_ACB; crySFX = crySFX_ACB; crySittingSFX = crySFX_ACB; panicSFX = panicSFX_ACB; killPlayerSFX = killPlayerSFX_ACB; break; case "SecretLab": screamSFX = screamSFX_SL; crySFX = crySFX_SL; crySittingSFX = crySFX_SL; panicSFX = panicSFX_SL; killPlayerSFX = killPlayerSFX_SL; break; } localPlayerCamera = ((Component)GameNetworkManager.Instance.localPlayerController.gameplayCamera).transform; spawnPosition = ((Component)this).transform.position; base.isOutside = ((Component)this).transform.position.y > -80f; mainEntrance = RoundManager.FindMainEntranceScript(base.isOutside); mainEntrancePosition = RoundManager.Instance.GetNavMeshPosition(RoundManager.FindMainEntrancePosition(true, base.isOutside), default(NavMeshHit), 5f, -1); base.path1 = new NavMeshPath(); if (outsideTeleports.Any()) { outsideTeleports.Clear(); } if (insideTeleports.Any()) { insideTeleports.Clear(); } entranceTeleports = Object.FindObjectsByType<EntranceTeleport>((FindObjectsSortMode)0); for (int i = 0; i < entranceTeleports.Length; i++) { int entranceId = entranceTeleports[i].entranceId; if (entranceTeleports[i].isEntranceToBuilding) { if (entranceTeleports[i].FindExitPoint() && !((Object)(object)entranceTeleports[i].entrancePoint == (Object)null)) { outsideTeleports.Add(entranceTeleports[i]); outsideTeleports.Sort((EntranceTeleport entranceA, EntranceTeleport entranceB) => entranceA.entranceId.CompareTo(entranceB.entranceId)); } } else if (entranceTeleports[i].FindExitPoint() && !((Object)(object)entranceTeleports[i].entrancePoint == (Object)null)) { insideTeleports.Add(entranceTeleports[i]); insideTeleports.Sort((EntranceTeleport entranceA, EntranceTeleport entranceB) => entranceA.entranceId.CompareTo(entranceB.entranceId)); } } if (base.isOutside) { if (base.allAINodes == null || base.allAINodes.Length == 0) { base.allAINodes = GameObject.FindGameObjectsWithTag("OutsideAINode"); } if ((Object)(object)GameNetworkManager.Instance.localPlayerController != (Object)null) { ((EnemyAI)this).EnableEnemyMesh(!StartOfRound.Instance.hangarDoorsClosed || !GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom, false); } } else if (base.allAINodes == null || base.allAINodes.Length == 0) { base.allAINodes = GameObject.FindGameObjectsWithTag("AINode"); } base.openDoorSpeedMultiplier = 450f; SetShyGuyInitialValues(); } private void CalculateAnimationSpeed() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Component)this).transform.position - previousPosition; float num = ((Vector3)(ref val)).magnitude; if (num > 0f) { num = 1f; } lastRunSpeed = Mathf.Lerp(lastRunSpeed, num, 5f * Time.deltaTime); base.creatureAnimator.SetFloat("VelocityZ", lastRunSpeed); previousPosition = ((Component)this).transform.position; } public override void DoAIInterval() { //IL_043f: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_053e: Unknown result type (might be due to invalid IL or missing references) //IL_054e: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_04a0: Unknown result type (might be due to invalid IL or missing references) //IL_04a5: Unknown result type (might be due to invalid IL or missing references) //IL_0826: Unknown result type (might be due to invalid IL or missing references) //IL_082d: Unknown result type (might be due to invalid IL or missing references) //IL_0833: Unknown result type (might be due to invalid IL or missing references) //IL_083b: Unknown result type (might be due to invalid IL or missing references) //IL_05eb: Unknown result type (might be due to invalid IL or missing references) //IL_077f: Unknown result type (might be due to invalid IL or missing references) //IL_078f: Unknown result type (might be due to invalid IL or missing references) //IL_0606: Unknown result type (might be due to invalid IL or missing references) //IL_07d9: Unknown result type (might be due to invalid IL or missing references) //IL_07ac: Unknown result type (might be due to invalid IL or missing references) //IL_0616: Unknown result type (might be due to invalid IL or missing references) //IL_0625: Unknown result type (might be due to invalid IL or missing references) //IL_0645: Unknown result type (might be due to invalid IL or missing references) //IL_0654: Unknown result type (might be due to invalid IL or missing references) //IL_067f: Unknown result type (might be due to invalid IL or missing references) //IL_0685: Unknown result type (might be due to invalid IL or missing references) //IL_06f0: Unknown result type (might be due to invalid IL or missing references) //IL_06f6: Unknown result type (might be due to invalid IL or missing references) ((EnemyAI)this).DoAIInterval(); if (StartOfRound.Instance.livingPlayers == 0) { lastInterval = Time.realtimeSinceStartup; return; } if (base.isEnemyDead) { lastInterval = Time.realtimeSinceStartup; return; } if (!((NetworkBehaviour)this).IsServer && ((NetworkBehaviour)this).IsOwner && base.currentBehaviourStateIndex != 2) { ((EnemyAI)this).ChangeOwnershipOfEnemy(StartOfRound.Instance.allPlayerScripts[0].actualClientId); } switch (base.currentBehaviourStateIndex) { case 0: { if (base.stunNormalizedTimer > 0f || sitting) { base.agent.speed = 0f; } else { roamWaitTime -= Time.realtimeSinceStartup - lastInterval; base.openDoorSpeedMultiplier = 1f; base.agent.speed = 2.75f * Config.speedDocileMultiplier; } base.movingTowardsTargetPlayer = false; base.agent.stoppingDistance = 4f; base.addPlayerVelocityToDestination = 0f; PlayerControllerB targetPlayer2 = base.targetPlayer; if (roamWaitTime <= 20f && roamMap.inProgress && (Object)(object)targetPlayer2 == (Object)null) { ((EnemyAI)this).StopSearch(roamMap, true); lastInterval = Time.realtimeSinceStartup; } else if (roamWaitTime > 2.5f && roamWaitTime <= 15f && !roamMap.inProgress && (Object)(object)targetPlayer2 == (Object)null && roamShouldSit) { sitting = true; base.creatureAnimator.SetBool("Sitting", true); float time = base.creatureVoice.time; base.creatureVoice.volume = 0.3f; base.creatureVoice.clip = crySittingSFX; base.creatureVoice.Play(); base.creatureVoice.time = time; lastInterval = Time.realtimeSinceStartup; } else { if ((Object)(object)targetPlayer2 != (Object)null || !((Object)(object)targetPlayer2 == (Object)null) || roamMap.inProgress || !(roamWaitTime <= 0f)) { break; } if (!sitting) { roamShouldSit = Random.Range(1, 5) == 1; roamWaitTime = Random.Range(25f, 32.5f); if (!roamShouldSit) { ((EnemyAI)this).StartSearch(spawnPosition, roamMap); } lastInterval = Time.realtimeSinceStartup; } else { sitting = false; roamShouldSit = false; roamWaitTime = Random.Range(21f, 25f); base.creatureAnimator.SetBool("Sitting", false); float time2 = base.creatureVoice.time; base.creatureVoice.volume = 0.3f; base.creatureVoice.clip = crySFX; base.creatureVoice.Play(); base.creatureVoice.time = time2; lastInterval = Time.realtimeSinceStartup; } } break; } case 1: base.agent.speed = 0f; lastInterval = Time.realtimeSinceStartup; base.movingTowardsTargetPlayer = false; break; case 2: { base.agent.stoppingDistance = 0f; base.agent.avoidancePriority = 99; base.openDoorSpeedMultiplier = 450f; mainCollider.isTrigger = true; base.addPlayerVelocityToDestination = 1f; if (inKillAnimation) { base.agent.speed = 0f; } else { base.agent.speed = Mathf.Clamp(base.agent.speed + (Time.realtimeSinceStartup - lastInterval) * Config.speedRageMultiplier * 1.1f, 5f * Config.speedRageMultiplier, 14.75f * Config.speedRageMultiplier); } if (SCP096Targets.Count <= 0) { SitDown(); break; } PlayerControllerB targetPlayer = base.targetPlayer; float num = float.PositiveInfinity; for (int num2 = SCP096Targets.Count - 1; num2 >= 0; num2--) { PlayerControllerB val = SCP096Targets[num2]; bool flag = val.isInsideFactory == !base.isOutside; bool flag2 = Config.canExitFacility || flag; if (!val.isPlayerDead && flag2) { float num3 = Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position); if (val.isPlayerControlled && (Object)(object)val.inAnimationWithEnemy == (Object)null && val.sinkingValue < 0.73f && num3 < num) { num = Vector3.Magnitude(((Component)val).transform.position - ((Component)this).transform.position); base.targetPlayer = val; ScopophobiaPlugin.Instance.LogInfoExtended($"{base.targetPlayer.playerClientId} is Hunted!"); } } else { ScopophobiaPlugin.Instance.LogInfoExtended($"Removing {val.actualClientId} from the Array"); AddTargetToList((int)val.actualClientId, remove: true); } } if ((Object)(object)base.targetPlayer != (Object)null) { base.creatureAnimator.SetFloat("DistanceToTarget", Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position)); if (roamMap.inProgress) { ((EnemyAI)this).StopSearch(roamMap, true); } if ((Object)(object)base.targetPlayer != (Object)(object)targetPlayer) { ((EnemyAI)this).ChangeOwnershipOfEnemy(base.targetPlayer.actualClientId); } if (base.isOutside && base.targetPlayer.isInHangarShipRoom && !pryingOpenDoor && BreakIntoShip()) { break; } if (!base.isOutside && (Object)(object)elevatorScript != (Object)null && base.agent.CalculatePath(((Component)base.targetPlayer).transform.position, base.path1) && (int)base.path1.status != 0) { if (Vector3.Distance(((Component)this).transform.position, elevatorScript.elevatorBottomPoint.position) < 7f) { isInElevatorStartRoom = false; } else if (Vector3.Distance(((Component)this).transform.position, elevatorScript.elevatorTopPoint.position) < 7f) { isInElevatorStartRoom = true; } if (!isInElevatorStartRoom) { if (Vector3.Distance(((Component)base.targetPlayer).transform.position, mainEntrancePosition) < 12f || !base.targetPlayer.isInsideFactory) { UseElevator(goUp: true); ScopophobiaPlugin.logger.LogInfo((object)"Flag 2 set, Shy Guy Going Up"); } break; } if (!base.targetPlayer.isPlayerDead && base.targetPlayer.isPlayerControlled && base.targetPlayer.isInsideFactory) { if (Vector3.Distance(((Component)base.targetPlayer).transform.position, mainEntrancePosition) > 12f) { UseElevator(goUp: false); ScopophobiaPlugin.logger.LogInfo((object)"Flag 3 set, Shy Guy Going Down"); } break; } } if (base.targetPlayer.isInsideFactory != !base.isOutside) { if (!pathingToTeleport) { ScopophobiaPlugin.Instance.LogInfoExtended($"{((Object)base.targetPlayer).name} Is Outside: {base.targetPlayer.isInsideFactory}, Looking for Teleport"); GetClosestTeleportAndMove(); } else if (Vector3.Distance(((Component)this).transform.position, closestTeleport.entrancePoint.position) < 2.5f) { TeleAndRefreshEnemy(closestTeleport.exitPoint.position, !base.isOutside); base.agent.speed = 0f; } else { base.movingTowardsTargetPlayer = false; ((EnemyAI)this).SetDestinationToPosition(closestTeleportPosition, false); ScopophobiaPlugin.Instance.LogInfoExtended($"{((Object)base.targetPlayer).name} is not in area, heading to closest Tele: {closestTeleport.entranceId}"); } } else if (((EnemyAI)this).PathIsIntersectedByLineOfSight(RoundManager.Instance.GetNavMeshPosition(((Component)base.targetPlayer).transform.position, default(NavMeshHit), 5f, -1), false, false, true)) { ((EnemyAI)this).SetMovingTowardsTargetPlayer(base.targetPlayer); } else { ((EnemyAI)this).SetMovingTowardsTargetPlayer(base.targetPlayer); } } else if (SCP096Targets.Count <= 0) { SitDown(); } break; } default: lastInterval = Time.realtimeSinceStartup; break; } } public void GetClosestTeleportAndMove() { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_007c: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) if (pathingToTeleport) { return; } List<EntranceTeleport> list = (base.targetPlayer.isInsideFactory ? outsideTeleports : insideTeleports); float num = Vector3.Distance(((Component)this).transform.position, mainEntrance.entrancePoint.position); EntranceTeleport val = mainEntrance; foreach (EntranceTeleport item in list) { if (!item.FindExitPoint() || (Object)(object)item.entrancePoint == (Object)null) { continue; } NavMeshPath val2 = new NavMeshPath(); if (!base.agent.CalculatePath(item.entrancePoint.position, val2) || (int)val2.status == 0) { float num2 = Vector3.Distance(((Component)this).transform.position, item.entrancePoint.position); if (num2 < num) { num = num2; val = item; } } } if ((Object)(object)val == (Object)(object)mainEntrance) { ScopophobiaPlugin.Instance.LogInfoExtended($"No closer teleport found. Heading to main entrance: {mainEntrance.entranceId}"); } else { ScopophobiaPlugin.Instance.LogInfoExtended($"Closest teleport found: {val.entranceId}. Pathing there."); } closestTeleport = val; closestTeleportPosition = val.entrancePoint.position; pathingToTeleport = true; } public void TeleAndRefreshEnemy(Vector3 Pos, bool setOutside) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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) //IL_004d: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) Vector3 navMeshPosition = RoundManager.Instance.GetNavMeshPosition(Pos, default(NavMeshHit), 5f, -1); if (((NetworkBehaviour)this).IsOwner) { ((Behaviour)base.agent).enabled = false; ((Component)this).transform.position = navMeshPosition; ((Behaviour)base.agent).enabled = true; base.agent.Warp(navMeshPosition); } else { ((Component)this).transform.position = navMeshPosition; } base.serverPosition = navMeshPosition; SetEnemyOutside(setOutside); pathingToTeleport = false; if (closestTeleport.doorAudios != null && closestTeleport.doorAudios.Length != 0) { closestTeleport.entrancePointAudio.PlayOneShot(closestTeleport.doorAudios[0]); WalkieTalkie.TransmitOneShotAudio(closestTeleport.entrancePointAudio, closestTeleport.doorAudios[0], 1f); } closestTeleport = null; pathingToTeleport = false; closestTeleportPosition = mainEntrancePosition; } private bool UseElevator(bool goUp) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_019a: 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_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0200: 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) Vector3 val = ((!goUp) ? elevatorScript.elevatorTopPoint.position : elevatorScript.elevatorBottomPoint.position); Debug.Log((object)$"goUp: {goUp}"); Debug.Log((object)$"{elevatorScript.elevatorFinishedMoving}, {!((EnemyAI)this).PathIsIntersectedByLineOfSight(elevatorScript.elevatorInsidePoint.position, false, false, false)}"); if (elevatorScript.elevatorFinishedMoving && !((EnemyAI)this).PathIsIntersectedByLineOfSight(elevatorScript.elevatorInsidePoint.position, false, false, false)) { Debug.Log((object)$"goUp: {goUp}, elevatormovingdown: {elevatorScript.elevatorMovingDown}"); Debug.Log((object)$"{elevatorScript.elevatorDoorOpen}, {Vector3.Distance(((Component)this).transform.position, elevatorScript.elevatorInsidePoint.position) < 1f}, {elevatorScript.elevatorMovingDown == goUp}"); if (elevatorScript.elevatorDoorOpen && Vector3.Distance(((Component)this).transform.position, elevatorScript.elevatorInsidePoint.position) < 1f && elevatorScript.elevatorMovingDown == goUp) { elevatorScript.PressElevatorButtonOnServer(true); } ((EnemyAI)this).SetDestinationToPosition(elevatorScript.elevatorInsidePoint.position, false); return true; } if (Vector3.Distance(((Component)this).transform.position, elevatorScript.elevatorInsidePoint.position) > 1f && !((EnemyAI)this).PathIsIntersectedByLineOfSight(val, false, false, false)) { if (elevatorScript.elevatorDoorOpen && Vector3.Distance(((Component)this).transform.position, val) < 1f && elevatorScript.elevatorMovingDown != goUp && !elevatorScript.elevatorCalled) { elevatorScript.CallElevatorOnServer(goUp); } ((EnemyAI)this).SetDestinationToPosition(val, false); return true; } if (elevatorScript.elevatorFinishedMoving) { ((EnemyAI)this).SetMovingTowardsTargetPlayer(base.targetPlayer); return false; } return false; } public override void Update() { //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018e: 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_0301: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) if (base.isEnemyDead || (Object)(object)GameNetworkManager.Instance == (Object)null) { return; } CalculateAnimationSpeed(); if (pryingOpenDoor && base.inSpecialAnimation) { ((Component)this).transform.position = Vector3.Lerp(((Component)this).transform.position, shipDoor.outsideDoorPoint.position, 7f * Time.deltaTime); ((Component)this).transform.rotation = Quaternion.Lerp(((Component)this).transform.rotation, shipDoor.outsideDoorPoint.rotation, 7f * Time.deltaTime); pryingDoorAnimTime = Mathf.Min(pryingDoorAnimTime + Time.deltaTime / pryOpenDoorAnimLength, 1f); base.creatureAnimator.SetFloat("pryOpenDoor", pryingDoorAnimTime); shipDoor.shipDoorsAnimator.SetFloat("pryOpenDoor", pryingDoorAnimTime); base.creatureAnimator.SetLayerWeight(0, Mathf.Max(0f, base.creatureAnimator.GetLayerWeight(0) - Time.deltaTime * 5f)); if (pryingDoorAnimTime > 0.12f) { ((EnemyAI)this).EnableEnemyMesh(true, false); } BreakIntoShip(); return; } canSeeFace = GameNetworkManager.Instance.localPlayerController.HasLineOfSightToPosition(shyGuyFace.position, Config.faceTriggerRange, 45, -1f); if (canSeeFace) { float num = Quaternion.Angle(((Component)GameNetworkManager.Instance.localPlayerController.gameplayCamera).transform.rotation, shyGuyFace.rotation); if (!(num <= 145f)) { canSeeFace = false; } } if (canSeeFace) { seeFaceTime += Time.deltaTime; if (seeFaceTime >= Config.faceTriggerGracePeriod) { GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(1.25f, true); if (!Config.hasMaxTargets || SCP096Targets.Count < Config.maxTargets) { ScopophobiaPlugin.Instance.LogInfoExtended($"Adding {GameNetworkManager.Instance.localPlayerController.playerClientId} To Targets. Has Seen Face: {canSeeFace}"); AddTargetToList((int)GameNetworkManager.Instance.localPlayerController.playerClientId); } if (base.currentBehaviourStateIndex == 0) { ScopophobiaPlugin.Instance.LogInfoExtended("Switching to triggered State"); ((EnemyAI)this).SwitchToBehaviourState(1); } } } else { seeFaceTime = Mathf.Clamp(seeFaceTime - Time.deltaTime, 0f, timeToTrigger); if (GameNetworkManager.Instance.localPlayerController.HasLineOfSightToPosition(((Component)this).transform.position + Vector3.up * 1f, 30f, 60, -1f) && base.currentBehaviourStateIndex == 0) { if (!base.thisNetworkObject.IsOwner) { ((EnemyAI)this).ChangeOwnershipOfEnemy(GameNetworkManager.Instance.localPlayerController.actualClientId); } if (Vector3.Distance(((Component)this).transform.position, ((Component)GameNetworkManager.Instance.localPlayerController).transform.position) < 10f) { GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(0.65f, true); } else { GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(0.25f, true); } } } switch (base.currentBehaviourStateIndex) { case 0: if (previousState != 0) { SetShyGuyInitialValues(); previousState = 0; mainCollider.isTrigger = true; farAudio.volume = 0f; PlayAudioFxOnLocalClient(1); } if (!base.creatureVoice.isPlaying) { PlayAudioFxOnLocalClient(1); } break; case 1: if (previousState != 1) { previousState = 1; sitting = false; mainCollider.isTrigger = true; base.creatureAnimator.SetBool("Rage", false); base.creatureAnimator.SetBool("Sitting", false); base.creatureAnimator.SetBool("triggered", true); PlayAudioFxOnLocalClient(2); base.agent.speed = 0f; triggerTime = triggerDuration; } triggerTime -= Time.deltaTime; if (triggerTime <= 0f) { ((EnemyAI)this).SwitchToBehaviourState(2); } break; case 2: if (previousState != 2) { mainCollider.isTrigger = true; previousState = 2; base.creatureAnimator.SetBool("Rage", true); base.creatureAnimator.SetBool("triggered", false); PlayAudioFxOnLocalClient(3); } break; } ((EnemyAI)this).Update(); } public void PlayAudioFxOnLocalClient(int audioClipID) { float num = Mathf.Clamp01(Config.VolumeConfigs * 0.1f); switch (audioClipID) { case 0: if (farAudio.isPlaying) { farAudio.Stop(); } if (base.creatureVoice.isPlaying) { base.creatureVoice.Stop(); } base.creatureVoice.volume = Mathf.Clamp01(Config.VolumeConfigs); base.creatureVoice.clip = crySittingSFX; base.creatureVoice.time = 0f; base.creatureVoice.Play(); break; case 1: base.creatureVoice.Stop(); base.creatureVoice.volume = Config.VolumeConfigs * 0.1f; base.creatureVoice.clip = crySFX; base.creatureVoice.time = 0f; base.creatureVoice.Play(); break; case 2: base.creatureVoice.Stop(); farAudio.volume = Config.VolumeConfigs * 0.1f; farAudio.clip = panicSFX; farAudio.time = 0f; farAudio.Play(); break; case 3: farAudio.Stop(); farAudio.volume = Config.VolumeConfigs * 0.1f - 0.1f; farAudio.clip = screamSFX; farAudio.time = 0f; farAudio.Play(); break; } } private IEnumerator PlaySittingSound() { yield return (object)new WaitForSeconds(0.05f); base.creatureVoice.volume = Mathf.Clamp01(Config.VolumeConfigs * 0.1f); base.creatureVoice.clip = crySittingSFX; base.creatureVoice.time = 0f; base.creatureVoice.Play(); } public void SetEnemyOutside(bool outside = false) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) base.isOutside = outside; mainEntrancePosition = RoundManager.Instance.GetNavMeshPosition(RoundManager.FindMainEntrancePosition(true, outside), default(NavMeshHit), 5f, -1); if (outside) { base.allAINodes = GameObject.FindGameObjectsWithTag("OutsideAINode"); } else { base.allAINodes = GameObject.FindGameObjectsWithTag("AINode"); } } public override void OnCollideWithPlayer(Collider other) { if (!Object.op_Implicit((Object)(object)((Component)other).gameObject.GetComponent<PlayerControllerB>())) { return; } ((EnemyAI)this).OnCollideWithPlayer(other); if (!inKillAnimation && !base.isEnemyDead && base.currentBehaviourStateIndex == 2) { PlayerControllerB val = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false); if ((Object)(object)val != (Object)null) { inKillAnimation = true; ((MonoBehaviour)this).StartCoroutine(killPlayerAnimation((int)val.playerClientId)); KillPlayerServerRpc((int)val.playerClientId); } } } [ServerRpc(RequireOwnership = false)] private void KillPlayerServerRpc(int playerId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: 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) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2556963367u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, playerId); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2556963367u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; KillPlayerClientRpc(playerId); } } } [ClientRpc] private void KillPlayerClientRpc(int playerId) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: 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) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2298532976u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, playerId); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2298532976u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; ((MonoBehaviour)this).StartCoroutine(killPlayerAnimation(playerId)); } } } private IEnumerator killPlayerAnimation(int playerId) { inKillAnimation = true; PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[playerId]; if (base.isOutside && ((Component)this).transform.position.y < -80f) { SetEnemyOutside(); } else if (!base.isOutside && ((Component)this).transform.position.y > -80f) { SetEnemyOutside(outside: true); } int count = SCP096Targets.Count; val.KillPlayer(((Component)val).transform.position, true, (CauseOfDeath)6, 1, default(Vector3)); AddTargetToList(playerId, remove: true); base.creatureSFX.clip = killPlayerSFX; base.creatureSFX.Play(); base.creatureAnimator.SetInteger("TargetsLeft", count - 1); base.creatureAnimator.SetTrigger("kill"); if (count - 1 <= 0) { SitDown(); } if (Config.deathMakesBloody && (Object)(object)bloodyMaterial != (Object)null) { Transform val2 = ((Component)this).transform.Find("SCP096Model"); if ((Object)(object)val2 != (Object)null) { Transform val3 = val2.Find("tsg_placeholder"); if ((Object)(object)val3 != (Object)null) { SkinnedMeshRenderer component = ((Component)val3).GetComponent<SkinnedMeshRenderer>(); if ((Object)(object)component != (Object)null) { ((Renderer)component).material = bloodyMaterial; } } } } yield return (object)new WaitForSeconds(1f); inKillAnimation = false; } public void SitDown() { ((EnemyAI)this).SwitchToBehaviourState(0); SitDownOnLocalClient(); SitDownServerRpc(); } [ServerRpc(RequireOwnership = false)] private void SitDownServerRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: 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) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(652446748u, val, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 652446748u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; SitDownClientRpc(); } } } [ClientRpc] private void SitDownClientRpc() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Invalid comparison between Unknown and I4 //IL_005f: 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) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2536632143u, val, (RpcDelivery)0); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2536632143u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; SitDownOnLocalClient(); } } } public void SitDownOnLocalClient() { sitting = true; roamWaitTime = Random.Range(45f, 50f); base.creatureAnimator.SetBool("Rage", false); base.creatureAnimator.SetBool("Sitting", true); } public void AddTargetToList(int playerId, bool remove = false) { PlayerControllerB item = StartOfRound.Instance.allPlayerScripts[playerId]; if (remove) { if (!SCP096Targets.Contains(item)) { return; } } else if (SCP096Targets.Contains(item)) { return; } AddTargetToListOnLocalClient(playerId, remove); AddTargetToListServerRpc(playerId, remove); } [ServerRpc(RequireOwnership = false)] public void AddTargetToListServerRpc(int playerId, bool remove) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Invalid comparison between Unknown and I4 //IL_005f: 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) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(1207108010u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, playerId); ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref remove, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 1207108010u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; AddTargetToListClientRpc(playerId, remove); } } } [ClientRpc] public void AddTargetToListClientRpc(int playerId, bool remove) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Invalid comparison between Unknown and I4 //IL_005f: 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) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1413965488u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, playerId); ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref remove, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1413965488u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; AddTargetToListOnLocalClient(playerId, remove); } } } public void AddTargetToListOnLocalClient(int playerId, bool remove) { PlayerControllerB item = StartOfRound.Instance.allPlayerScripts[playerId]; if (remove) { if (SCP096Targets.Contains(item)) { SCP096Targets.Remove(item); } } else if (!SCP096Targets.Contains(item)) { SCP096Targets.Add(item); } } private void BeginPryOpenDoor() { StartPryOpenDoorAnimationOnLocalClient(); PryOpenDoorServerRpc((int)GameNetworkManager.Instance.localPlayerController.actualClientId); } private void FinishPryOpenDoor(bool cancelledEarly) { FinishPryOpenDoorAnimationOnLocalClient(cancelledEarly); PryOpenDoorServerRpc((int)GameNetworkManager.Instance.localPlayerController.actualClientId, finishAnim: true, cancelledEarly); } [ServerRpc(RequireOwnership = false)] public void PryOpenDoorServerRpc(int playerWhoSent, bool finishAnim = false, bool cancelledEarly = false) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Invalid comparison between Unknown and I4 //IL_005f: 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) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(3983190202u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, playerWhoSent); ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref finishAnim, default(ForPrimitives)); ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref cancelledEarly, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 3983190202u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; PryOpenDoorClientRpc(playerWhoSent, finishAnim, cancelledEarly); } } } [ClientRpc] public void PryOpenDoorClientRpc(int playerWhoSent, bool finishAnim = false, bool cancelledEarly = false) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Invalid comparison between Unknown and I4 //IL_005f: 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) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager == null || !networkManager.IsListening) { return; } if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(2274076407u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, playerWhoSent); ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref finishAnim, default(ForPrimitives)); ((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref cancelledEarly, default(ForPrimitives)); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 2274076407u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; if (!finishAnim) { StartPryOpenDoorAnimationOnLocalClient(); } else { FinishPryOpenDoorAnimationOnLocalClient(cancelledEarly); } } } private void FinishPryOpenDoorAnimationOnLocalClient(bool cancelledEarly = false) { if (!cancelledEarly) { shipDoor.shipDoorsAnimator.SetBool("Closed", false); StartOfRound.Instance.SetShipDoorsClosed(false); StartOfRound.Instance.SetShipDoorsOverheatLocalClient(); shipDoor.doorPower = 0f; } pryingOpenDoor = false; base.inSpecialAnimation = false; base.creatureAnimator.SetBool("PryingOpenDoor", false); shipDoor.shipDoorsAnimator.SetBool("PryingOpenDoor", false); base.creatureAnimator.SetLayerWeight(0, 1f); } private void StartPryOpenDoorAnimationOnLocalClient() { //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) ((Behaviour)base.agent).enabled = false; pryingOpenDoor = true; base.inSpecialAnimation = true; base.creatureAnimator.SetBool("PryingOpenDoor", true); shipDoor.shipDoorsAnimator.SetBool("PryingOpenDoor", true); shipDoor.shipDoorsAnimator.SetFloat("pryOpenDoor", 0f); breakDownDoorAudio.PlayOneShot(breakAndEnter); WalkieTalkie.TransmitOneShotAudio(breakDownDoorAudio, breakAndEnter, 1f); RoundManager.Instance.PlayAudibleNoise(((Component)this).transform.position, 15f, 0.9f, 0, false, 0); StartOfRound.Instance.speakerAudioSource.PlayOneShot(shipAlarm); WalkieTalkie.TransmitOneShotAudio(StartOfRound.Instance.speakerAudioSource, shipAlarm, 1f); if (Vector3.Distance(((Component)StartOfRound.Instance.audioListener).transform.position, ((Component)this).transform.position) < 18f) { HUDManager.Instance.ShakeCamera((ScreenShakeType)3); } } public bool BreakIntoShip() { if ((Object)(object)shipDoor == (Object)null) { Debug.LogError((object)"Scopophobia error: ship door is null"); return false; } if (pryingOpenDoor) { if (pryingDoorAnimTime >= 1f) { FinishPryOpenDoor(cancelledEarly: false); } return true; } if (CanStartPrying()) { BeginPryOpenDoor(); return true; } return false; } private bool CanStartPrying() { if (StartOfRound.Instance.hangarDoorsClosed && IsDestinationInShip()) { return IsNearShipDoor(); } return false; } private bool IsDestinationInShip() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) Bounds bounds = StartOfRound.Instance.shipStrictInnerRoomBounds.bounds; return ((Bounds)(ref bounds)).Contains(base.destination); } private bool IsNearShipDoor() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) return Vector3.Distance(((Component)this).transform.position, shipDoor.outsideDoorPoint.position) < 4f; } private void SetShyGuyInitialValues() { mainCollider = ((Component)this).gameObject.GetComponentInChildren<Collider>(); farAudio = ((Component)((Component)this).transform.Find("FarAudio")).GetComponent<AudioSource>(); base.creatureVoice = ((Component)((Component)this).transform.Find("CreatureVoice")).GetComponent<AudioSource>(); base.targetPlayer = null; inKillAnimation = false; pryingOpenDoor = false; base.updateDestinationInterval = 0.1f; base.agent.autoTraverseOffMeshLink = true; SCP096Targets.Clear(); base.creatureAnimator.SetFloat("VelocityX", 0f); base.creatureAnimator.SetFloat("VelocityZ", 0f); base.creatureAnimator.SetFloat("DistanceToTarget", 999f); base.creatureAnimator.SetFloat("pryOpenDoor", 999f); base.creatureAnimator.SetInteger("SitActionTimer", 0); base.creatureAnimator.SetInteger("TargetsLeft", 0); base.creatureAnimator.SetBool("Rage", false); base.creatureAnimator.SetBool("Sitting", false); base.creatureAnimator.SetBool("triggered", false); base.creatureAnimator.SetBool("PryingOpenDoor", false); mainCollider.isTrigger = true; farAudio.volume = 0f; farAudio.Stop(); base.creatureVoice.Stop(); } protected override void __initializeVariables() { if (syncedAudioClipID == null) { throw new Exception("ShyGuyAI.syncedAudioClipID cannot be null. All NetworkVariableBase instances must be initialized."); } ((NetworkVariableBase)syncedAudioClipID).Initialize((NetworkBehaviour)(object)this); ((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)syncedAudioClipID, "syncedAudioClipID"); ((NetworkBehaviour)this).NetworkVariableFields.Add((NetworkVariableBase)(object)syncedAudioClipID); ((EnemyAI)this).__initializeVariables(); } protected override void __initializeRpcs() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Expected O, but got Unknown //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Expected O, but got Unknown ((NetworkBehaviour)this).__registerRpc(2556963367u, new RpcReceiveHandler(__rpc_handler_2556963367), "KillPlayerServerRpc"); ((NetworkBehaviour)this).__registerRpc(2298532976u, new RpcReceiveHandler(__rpc_handler_2298532976), "KillPlayerClientRpc"); ((NetworkBehaviour)this).__registerRpc(652446748u, new RpcReceiveHandler(__rpc_handler_652446748), "SitDownServerRpc"); ((NetworkBehaviour)this).__registerRpc(2536632143u, new RpcReceiveHandler(__rpc_handler_2536632143), "SitDownClientRpc"); ((NetworkBehaviour)this).__registerRpc(1207108010u, new RpcReceiveHandler(__rpc_handler_1207108010), "AddTargetToListServerRpc"); ((NetworkBehaviour)this).__registerRpc(1413965488u, new RpcReceiveHandler(__rpc_handler_1413965488), "AddTargetToListClientRpc"); ((NetworkBehaviour)this).__registerRpc(3983190202u, new RpcReceiveHandler(__rpc_handler_3983190202), "PryOpenDoorServerRpc"); ((NetworkBehaviour)this).__registerRpc(2274076407u, new RpcReceiveHandler(__rpc_handler_2274076407), "PryOpenDoorClientRpc"); ((EnemyAI)this).__initializeRpcs(); } private static void __rpc_handler_2556963367(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int playerId = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref playerId); target.__rpc_exec_stage = (__RpcExecStage)1; ((ShyGuyAI)(object)target).KillPlayerServerRpc(playerId); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2298532976(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int playerId = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref playerId); target.__rpc_exec_stage = (__RpcExecStage)1; ((ShyGuyAI)(object)target).KillPlayerClientRpc(playerId); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_652446748(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((ShyGuyAI)(object)target).SitDownServerRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2536632143(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { target.__rpc_exec_stage = (__RpcExecStage)1; ((ShyGuyAI)(object)target).SitDownClientRpc(); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1207108010(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int playerId = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref playerId); bool remove = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref remove, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((ShyGuyAI)(object)target).AddTargetToListServerRpc(playerId, remove); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_1413965488(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int playerId = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref playerId); bool remove = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref remove, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((ShyGuyAI)(object)target).AddTargetToListClientRpc(playerId, remove); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_3983190202(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0057: 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) //IL_006c: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int playerWhoSent = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref playerWhoSent); bool finishAnim = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref finishAnim, default(ForPrimitives)); bool cancelledEarly = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref cancelledEarly, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((ShyGuyAI)(object)target).PryOpenDoorServerRpc(playerWhoSent, finishAnim, cancelledEarly); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2274076407(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0057: 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) //IL_006c: 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) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int playerWhoSent = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref playerWhoSent); bool finishAnim = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref finishAnim, default(ForPrimitives)); bool cancelledEarly = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref cancelledEarly, default(ForPrimitives)); target.__rpc_exec_stage = (__RpcExecStage)1; ((ShyGuyAI)(object)target).PryOpenDoorClientRpc(playerWhoSent, finishAnim, cancelledEarly); target.__rpc_exec_stage = (__RpcExecStage)0; } } [MethodImpl(MethodImplOptions.NoInlining)] protected internal override string __getTypeName() { return "ShyGuyAI"; } } } namespace Scopophobia { [Serializable] public class Config : SyncedInstance<Config> { [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnRequestSync; public static HandleNamedMessageDelegate <1>__OnReceiveSync; } public static ConfigEntry<bool> ExtendedLoggingConfig; public static ConfigEntry<bool> AppearsConfig; public static ConfigEntry<bool> HasGlowingEyesConfig; public static ConfigEntry<string> SoundPackConfig; public static ConfigEntry<bool> BloodyTextureConfig; public static ConfigEntry<bool> DeathMakesBloodyConfig; public static ConfigEntry<float> SpeedDocileMultiplierConfig; public static ConfigEntry<float> SpeedRageMultiplierConfig; public static ConfigEntry<float> VolumeConfig; public static ConfigEntry<float> TriggerTimeConfig; public static ConfigEntry<float> FaceTriggerRangeConfig; public static ConfigEntry<float> FaceTriggerGracePeriodConfig; public static ConfigEntry<bool> HasMaxTargetsConfig; public static ConfigEntry<int> MaxTargetsConfig; public static ConfigEntry<bool> CanExitFacilityConfig; public static ConfigEntry<string> SpawnProbabilityCurveConfig; public static ConfigEntry<float> ShyGuyPowerLevelConfig; public static ConfigEntry<int> paintingSpawnRateConfig; public static ConfigEntry<bool> hidePaintingNameConfig; public static ConfigEntry<string> nameToUseForPaintingConfig; public static ConfigEntry<int> ChanceOfShyGuyConfig; public static ConfigEntry<bool> TwitchIntegrationConfig; public static ConfigEntry<bool> ShouldSpawnInBeltBagConfig; public static bool ExtendedLogging; public static bool appears; public static bool hasGlowingEyes; public static string soundPack; public static bool bloodyTexture; public static bool deathMakesBloody; public static bool DisableSpawnRates; public static float speedDocileMultiplier; public static float speedRageMultiplier; public static float VolumeConfigs; public static float triggerTime; public static float faceTriggerRange; public static float faceTriggerGracePeriod; public static bool hasMaxTargets; public static int maxTargets; public static bool canExitFacility; public static string SpawnProbabilityCurve; public static float midEnemySpawnCurve; public static float endEnemySpawnCurve; public static bool spawnOutsideHardPlanets; public static bool twitchIntegration; public static float ShyGuyPowerLevel; public static int PaintingSpawnRate; public static bool hidePaintingName; public static string nameToUseForPainting; public static bool ShouldSpawnInBeltBag; public static int ChanceOfShyGuy; public static void SetModIcon(Sprite sprite) { if (LethalConfigProxy.Enabled) { LethalConfigProxy.SetModIcon(sprite); } } public static void SetModDescription(string description) { if (LethalConfigProxy.Enabled) { LethalConfigProxy.SetModDescription(description); } } public static void SkipAutoGen() { if (LethalConfigProxy.Enabled) { LethalConfigProxy.SkipAutoGen(); } } public Config(ConfigFile cfg) { InitInstance(this); BindConfigs(cfg); SetupChangedEvents(); } public void BindConfigs(ConfigFile cfg) { SkipAutoGen(); AppearsConfig = Bind("General", "Enable the Shy Guy", defaultValue: true, requiresRestart: true, "Allows the Shy Guy to spawn in-game."); ExtendedLoggingConfig = Bind("General", "Enable Extended Logging", defaultValue: false, requiresRestart: false, "Enables Error and Warning Logs [Developer]"); HasGlowingEyesConfig = Bind("Appearance", "Glowing Eyes", defaultValue: true, requiresRestart: false, "Gives the Shy Guy glowing eyes similar to the Bracken/Flowerman."); BloodyTextureConfig = Bind("Appearance", "Bloody Texture", defaultValue: false, requiresRestart: false, "Gives the Shy Guy his bloodier, original texture from SCP: Containment Breach."); DeathMakesBloodyConfig = Bind("Appearance", "Bloody Death", defaultValue: true, requiresRestart: false, "Causes the Shy Guy's material to become bloody once getting his first kill. Useless if Bloody Texture is enabled lol"); SoundPackConfig = Bind("Appearance", "Sound Pack (Curated, SCPCB, SCPCBOld, SecretLab)", "Curated", requiresRestart: false, "Determines the sounds the Shy Guy uses. (SOME MAY NOT SYNC WELL WITH TRIGGER TIME) (Curated = Default, curated for the Lethal Company experience) (SCPCB = SCP-096 sounds from SCP: Containment Breach) (SCPCBOld = Old alpha SCP-096 sounds from SCP: Containment Breach) (SecretLab = SCP-096 sounds from SCP: Secret Laboratory)"); SpeedDocileMultiplierConfig = Bind("General", "Speed Multiplier (Docile)", 1f, requiresRestart: false, "Determines the speed multiplier of the Shy Guy while docile."); SpeedRageMultiplierConfig = Bind("General", "Speed Multiplier (Rage)", 1f, requiresRestart: false, "Determines the speed multiplier of the Shy Guy while enraged."); VolumeConfig = Bind("General", "Enemy Volume", 5f, requiresRestart: false, "Determines the volume of the Shy Guy, and how loud he is. (Set this Anywhere between 0 and 10. Default: 5f, Old Default: 5f)"); TriggerTimeConfig = Bind("Trigger Settings", "Trigger Time", 66.4f, requiresRestart: true, "Determines how long the Shy Guy must remain in the Triggered state to become fully enraged."); FaceTriggerRangeConfig = Bind("Trigger Settings", "Face Trigger Range", 17.5f, requiresRestart: true, "Determines the face's trigger radius."); FaceTriggerGracePeriodConfig = Bind("Trigger Settings", "Face Trigger Grace Period", 0.5f, requiresRestart: true, "Determines the grace period when you see the face of the Shy Guy before he becomes enraged."); HasMaxTargetsConfig = Bind("Trigger Settings", "Has Max Targets", defaultValue: false, requiresRestart: true, "Determines if the Shy Guy has a maximum amount of targets."); MaxTargetsConfig = Bind("Trigger Settings", "Max Targets", 32, requiresRestart: true, "Determines the max amount of targets the Shy Guy can have. (requires HasMaxTargets)"); CanExitFacilityConfig = Bind("Trigger Settings", "Can Exit Facility", defaultValue: true, requiresRestart: false, "Determines if the Shy Guy can exit the facility and into the outdoors (and vice versa) to attack its target."); SpawnProbabilityCurveConfig = Bind("Spawn Settings", "ProbabilityCurve", "0.2, 1.0, 0.75", requiresRestart: false, "Determines how likely Shy Guy is to spawn throughout the day. Accepts an array of floats with each entry separated by a comma."); ShyGuyPowerLevelConfig = Bind("Spawn Settings", "Shy Guy Power Level", 3f, requiresRestart: false, "Default Power Level for the Shy Guy to take up per level. (Default: 3.0)"); paintingSpawnRateConfig = Bind("Painting Spawn Settings", "Shy Guy Painting Spawn Rarity", 5, requiresRestart: true, "Default Spawn Rarity for the ShyGuyPainting (Default: 5)"); hidePaintingNameConfig = Bind("Painting Spawn Settings", "Hide Painting Name before Interaction", defaultValue: true, requiresRestart: true, "Disguise the painting as a different Loot Item? (Default: True)"); nameToUseForPaintingConfig = Bind("Painting Spawn Settings", "Custom Painting Name", "Fancy Painting", requiresRestart: true, "Customise the Scannode name for the item on the map! (Default: Fancy Painting"); ChanceOfShyGuyConfig = Bind("Painting Spawn Settings", "Spawn Chance", 35, requiresRestart: true, "Customise the spawn chance of shy guy spawning from the painting. Higher values mean more likely, lower values mean less likely. (Set to 100 for guaranteed spawns"); ShouldSpawnInBeltBagConfig = Bind("Painting Spawn Settings", "Can Spawn via Belt Bag", defaultValue: true, requiresRestart: false, "Can the Shy Guy Spawn even if the Painting is inside the Belt Bag?"); appears = AppearsConfig.Value; ExtendedLogging = ExtendedLoggingConfig.Value; hasGlowingEyes = HasGlowingEyesConfig.Value; bloodyTexture = BloodyTextureConfig.Value; deathMakesBloody = DeathMakesBloodyConfig.Value; soundPack = SoundPackConfig.Value; speedDocileMultiplier = SpeedDocileMultiplierConfig.Value; speedRageMultiplier = SpeedRageMultiplierConfig.Value; VolumeConfigs = VolumeConfig.Value; triggerTime = TriggerTimeConfig.Value; faceTriggerRange = FaceTriggerRangeConfig.Value; faceTriggerGracePeriod = FaceTriggerGracePeriodConfig.Value; hasMaxTargets = HasMaxTargetsConfig.Value; maxTargets = MaxTargetsConfig.Value; canExitFacility = CanExitFacilityConfig.Value; SpawnProbabilityCurve = SpawnProbabilityCurveConfig.Value; ShyGuyPowerLevel = ShyGuyPowerLevelConfig.Value; PaintingSpawnRate = paintingSpawnRateConfig.Value; hidePaintingName = hidePaintingNameConfig.Value; nameToUseForPainting = nameToUseForPaintingConfig.Value; ChanceOfShyGuy = ChanceOfShyGuyConfig.Value; ShouldSpawnInBeltBag = ShouldSpawnInBeltBagConfig.Value; } private void SetupChangedEvents() { SpawnProbabilityCurveConfig.SettingChanged += SpawnProbabilityCurve_SettingChanged; } private void SpawnProbabilityCurve_SettingChanged(object sender, EventArgs e) { EnemyHelper.SetProbabilityCurve("Shy guy", Utils.ToFloatsArray(SpawnProbabilityCurveConfig.Value)); } public static void RequestSync() { //IL_0022: Unknown result type (might be due to invalid IL or missing references) if (!SyncedInstance<Config>.IsClient) { return; } FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(SyncedInstance<Config>.IntSize, (Allocator)2, -1); try { SyncedInstance<Config>.MessageManager.SendNamedMessage("Scopophobia_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } public static void OnRequestSync(ulong clientId, FastBufferReader _) { //IL_0050: 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_0072: Unknown result type (might be due to invalid IL or missing references) if (!SyncedInstance<Config>.IsHost) { return; } ScopophobiaPlugin.logger.LogInfo((object)$"Config sync request received from client: {clientId}"); byte[] array = SyncedInstance<Config>.SerializeToBytes(SyncedInstance<Config>.Instance); int num = array.Length; int num2 = FastBufferWriter.GetWriteSize<byte>(array, -1, 0) + SyncedInstance<Config>.IntSize; FastBufferWriter val = default(FastBufferWriter); ((FastBufferWriter)(ref val))..ctor(num2, (Allocator)2, -1); try { ((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0); SyncedInstance<Config>.MessageManager.SendNamedMessage("Scopophobia_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3); } catch (Exception arg) { ScopophobiaPlugin.logger.LogInfo((object)$"Error occurred syncing config with client: {clientId}\n{arg}"); } finally { ((IDisposable)(FastBufferWriter)(ref val)).Dispose(); } } public static ConfigEntry<T> Bind<T>(string section, string key, T defaultValue, bool requiresRestart, string description, AcceptableValueBase acceptableValues = null, Action<T> settingChanged = null, ConfigFile configFile = null) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown Action<T> settingChanged2 = settingChanged; if (configFile == null) { configFile = ((BaseUnityPlugin)ScopophobiaPlugin.Instance).Config; } ConfigEntry<T> configEntry = ((acceptableValues == null) ? configFile.Bind<T>(section, key, defaultValue, description) : configFile.Bind<T>(section, key, defaultValue, new ConfigDescription(description, acceptableValues, Array.Empty<object>()))); if (settingChanged2 != null) { configEntry.SettingChanged += delegate { settingChanged2?.Invoke(configEntry.Value); }; } if (LethalConfigProxy.Enabled) { if (acceptableValues == null) { LethalConfigProxy.AddConfig<T>(configEntry, requiresRestart); } else { LethalConfigProxy.AddConfigSlider<T>(configEntry, requiresRestart); } } return configEntry; } public static void OnReceiveSync(ulong _, FastBufferReader reader) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) if (!((FastBufferReader)(ref reader)).TryBeginRead(SyncedInstance<Config>.IntSize)) { ScopophobiaPlugin.logger.LogError((object)"Config sync error: Could not begin reading buffer."); return; } int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives)); if (!((FastBufferReader)(ref reader)).TryBeginRead(num)) { ScopophobiaPlugin.logger.LogError((object)"Config sync error: Host could not sync."); return; } byte[] data = new byte[num]; ((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0); SyncedInstance<Config>.SyncInstance(data); ScopophobiaPlugin.logger.LogInfo((object)"Successfully synced config with host."); } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] public static void InitializeLocalPlayer() { //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) //IL_0063: Expected O, but got Unknown //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_002c: Expected O, but got Unknown if (SyncedInstance<Config>.IsHost) { CustomMessagingManager messageManager = SyncedInstance<Config>.MessageManager; object obj = <>O.<0>__OnRequestSync; if (obj == null) { HandleNamedMessageDelegate val = OnRequestSync; <>O.<0>__OnRequestSync = val; obj = (object)val; } messageManager.RegisterNamedMessageHandler("Scopophobia_OnRequestConfigSync", (HandleNamedMessageDelegate)obj); SyncedInstance<Config>.Synced = true; return; } SyncedInstance<Config>.Synced = false; CustomMessagingManager messageManager2 = SyncedInstance<Config>.MessageManager; object obj2 = <>O.<1>__OnReceiveSync; if (obj2 == null) { HandleNamedMessageDelegate val2 = OnReceiveSync; <>O.<1>__OnReceiveSync = val2; obj2 = (object)val2; } messageManager2.RegisterNamedMessageHandler("Scopophobia_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2); RequestSync(); } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")] public static void PlayerLeave() { SyncedInstance<Config>.RevertSync(); } } internal static class EnemyDataManager { public const string EnemyName = "Shy guy"; private static bool _initialized; public static List<EnemyData> EnemyDataList { get; private set; } = new List<EnemyData>(); public static void Initialize() { if (!_initialized) { _initialized = true; InitializeEnemyDataList(); } } private static void InitializeEnemyDataList() { if ((Object)(object)StartOfRound.Instance == (Object)null) { Plugin.logger.LogError((object)"Failed to initialize enemy data list. StartOfRound Instance is null. (EnemyName: Shy guy)"); return; } EnemyType enemyType = EnemyHelper.GetEnemyType("Shy guy"); if ((Object)(object)enemyType == (Object)null) { Plugin.logger.LogError((object)"Failed to initialize enemy data list. EnemyType is null. (EnemyName: Shy guy)"); return; } EnemyHelper.SetProbabilityCurve("Shy guy", Utils.ToFloatsArray(Config.SpawnProbabilityCurveConfig.Value)); SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { if (val.spawnEnemiesAndScrap) { AddEnemyData(val); } } foreach (EnemyData enemyData in EnemyDataList) { int value = enemyData.ConfigData.SpawnWeight.Value; if (enemyData.ConfigData.SpawnInside.Value) { LevelHelper.AddEnemyToLevel(enemyData.PlanetName, "Shy guy", value, EnemyListType.Inside); } else { LevelHelper.RemoveEnemyFromLevel(enemyData.PlanetName, "Shy guy", EnemyListType.Inside); } if (enemyData.ConfigData.SpawnOutside.Value) { LevelHelper.AddEnemyToLevel(enemyData.PlanetName, "Shy guy", value, EnemyListType.Outside); } else { LevelHelper.RemoveEnemyFromLevel(enemyData.PlanetName, "Shy guy", EnemyListType.Outside); } } } public static void AddEnemyData(SelectableLevel level) { if (HasEnemyData(level.PlanetName)) { Plugin.logger.LogWarning((object)("Failed to add enemy data for level \"" + level.PlanetName + "\". Enemy data already exists for SelectableLevel.")); return; } EnemyType enemyType = EnemyHelper.GetEnemyType("Shy guy"); if ((Object)(object)enemyType == (Object)null) { Plugin.logger.LogError((object)("Failed to add enemy data for level \"" + level.PlanetName + "\". EnemyType is null")); return; } int spawnWeight; bool flag = LevelHelper.LevelHasEnemy(level.PlanetName, "Shy guy", EnemyListType.Inside, out spawnWeight); int spawnWeight2; bool flag2 = LevelHelper.LevelHasEnemy(level.PlanetName, "Shy guy", EnemyListType.Outside, out spawnWeight2); int spawnWeight3 = 0; if (flag && flag2) { spawnWeight3 = Mathf.Max(spawnWeight, spawnWeight2); } else if (flag) { spawnWeight3 = spawnWeight; } else if (flag2) { spawnWeight3 = spawnWeight2; } EnemyConfigDataDefault defaultConfigValues = new EnemyConfigDataDefault(spawnWeight3, enemyType.MaxCount, flag, flag2); EnemyData enemyData = new EnemyData(level.PlanetName, defaultConfigValues); enemyData.BindConfigs(); EnemyDataList.Add(enemyData); } public static EnemyData GetEnemyData(string planetName) { foreach (EnemyData enemyData in EnemyDataList) { if (enemyData.PlanetName == planetName) { return enemyData; } } return null; } public static bool HasEnemyData(string planetName) { return GetEnemyData(planetName) != null; } public static void SetEnemyDataForCurrentLevel() { EnemyData enemyData = GetEnemyData(LevelHelper.CurrentPlanetName); if (enemyData == null) { Plugin.logger.LogError((object)("Failed to set enemy data for current level. EnemyData is null. (PlanetName: " + LevelHelper.CurrentPlanetName + ")")); } else { EnemyHelper.SetMaxSpawnCount("Shy guy", enemyData.ConfigData.MaxSpawnCount.Value, LevelHelper.CurrentPlanetName); } } } public enum EnemyListType { Inside, Outside, Daytime } internal static class EnemyHelper { public static void SetSpawnWeight(string enemyName, int spawnWeight, EnemyListType enemyListType, string planetName) { if ((Object)(object)StartOfRound.Instance == (Object)null) { Plugin.logger.LogError((object)$"Failed to set enemy spawn weight. StartOfRound Instance is null. (EnemyName: {enemyName}, SpawnWeight: {spawnWeight}, EnemyListType: {Utils.GetEnumName(enemyListType)}, PlanetName: {planetName})"); return; } EnemyType enemyType = GetEnemyType(enemyName); if ((Object)(object)enemyType == (Object)null) { Plugin.logger.LogError((object)$"Failed to set enemy spawn weight. EnemyType is null. (EnemyName: {enemyName}, SpawnWeight: {spawnWeight}, EnemyListType: {Utils.GetEnumName(enemyListType)}, PlanetName: {planetName})"); return; } SelectableLevel levelByName = LevelHelper.GetLevelByName(planetName); if ((Object)(object)levelByName == (Object)null) { Plugin.logger.LogError((object)$"Failed to set enemy spawn weight. SelectableLevel is null. (EnemyName: {enemyName}, SpawnWeight: {spawnWeight}, EnemyListType: {Utils.GetEnumName(enemyListType)}, PlanetName: {planetName})"); return; } if (!LevelHelper.LevelHasEnemy(planetName, enemyName, enemyListType)) { Plugin.logger.LogError((object)$"Failed to set enemy spawn weight. SelectableLevel does not contain enemy. (EnemyName: {enemyName}, SpawnWeight: {spawnWeight}, EnemyListType: {Utils.GetEnumName(enemyListType)}, PlanetName: {planetName})"); return; } List<SpawnableEnemyWithRarity> enemyList = LevelHelper.GetEnemyList(levelByName, enemyListType); foreach (SpawnableEnemyWithRarity item in enemyList) { if ((Object)(object)item.enemyType == (Object)(object)enemyType) { item.rarity = spawnWeight; break; } } ScopophobiaPlugin.Instance.LogInfoExtended($"Set enemy spawn weight. (EnemyName: {enemyName}, SpawnWeight: {spawnWeight}, EnemyListType: {Utils.GetEnumName(enemyListType)}, PlanetName: {planetName})"); } public static void SetMaxSpawnCount(string enemyName, int maxSpawnCount, string planetName) { if ((Object)(object)StartOfRound.Instance == (Object)null) { Plugin.logger.LogError((object)$"Failed to set enemy max spawn count. StartOfRound Instance is null. (EnemyName: {enemyName}, MaxSpawnCount: {maxSpawnCount}, PlanetName: {planetName})"); return; } if (!LevelHelper.IsCurrentLevel(planetName)) { Plugin.logger.LogError((object)$"Failed to set enemy max spawn count. Planet name is not the current planet name. (EnemyName: {enemyName}, MaxSpawnCount: {maxSpawnCount}, PlanetName: {planetName})"); return; } EnemyType enemyType = GetEnemyType(enemyName); if ((Object)(object)enemyType == (Object)null) { Plugin.logger.LogError((object)$"Failed to set enemy max spawn count. EnemyType is null. (EnemyName: {enemyName}, MaxSpawnCount: {maxSpawnCount}, PlanetName: {planetName})"); return; } enemyType.MaxCount = maxSpawnCount; ScopophobiaPlugin.Instance.LogInfoExtended($"Set enemy max spawn count. (EnemyName: {enemyName}, MaxSpawnCount: {maxSpawnCount}, PlanetName: {planetName})"); } public static void SetProbabilityCurve(string enemyName, float[] values) { if (values == null) { Plugin.logger.LogError((object)("Failed to set enemy probability curve. Values are null. (EnemyName: " + enemyName + ")")); return; } if (values.Length == 0) { Plugin.logger.LogError((object)("Failed to set enemy probability curve. Values are empty. (EnemyName: " + enemyName + ")")); return; } if ((Object)(object)StartOfRound.Instance == (Object)null) { Plugin.logger.LogError((object)("Failed to set enemy probability curve. StartOfRound Instance is null. (EnemyName: " + enemyName + ", Values: " + string.Join(", ", values) + ")")); return; } EnemyType enemyType = GetEnemyType(enemyName); if ((Object)(object)enemyType == (Object)null) { Plugin.logger.LogError((object)("Failed to set enemy probability curve. EnemyType is null. (EnemyName: " + enemyName + ", Values: " + string.Join(", ", values) + ")")); return; } AnimationCurve val = Utils.CreateAnimationCurve(values); if (val == null) { Plugin.logger.LogError((object)("Failed to set enemy probability curve. AnimationCurve is invalid. (EnemyName: " + enemyName + ", Values: " + string.Join(", ", values) + ")")); } else { enemyType.probabilityCurve = val; ScopophobiaPlugin.Instance.LogInfoExtended("Set enemy probability curve. (EnemyName: " + enemyName + ", Values: " + string.Join(", ", values) + ")"); } } public static EnemyType GetEnemyType(string enemyName) { string enemyName2 = enemyName; foreach (EnemyType enemyType in GetEnemyTypes()) { if (enemyType.enemyName == enemyName2) { return enemyType; } } try { EnemyType val = Resources.FindObjectsOfTypeAll<EnemyType>().Single((EnemyType x) => x.enemyName == enemyName2); if (IsValidEnemyType(val) && NetworkUtils.IsNetworkPrefab(val.enemyPrefab)) { ScopophobiaPlugin.Instance.LogInfoExtended("Found EnemyType \"" + val.enemyName + "\" from Resources."); return val; } } catch { } return null; } public static List<EnemyType> GetEnemyTypes() { if ((Object)(object)StartOfRound.Instance == (Object)null) { return new List<EnemyType>(); } HashSet<EnemyType> hashSet = new HashSet<EnemyType>(new EnemyTypeComparer()); SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { IEnumerable<EnemyType> enumerable = (from e in val.Enemies.Concat(val.DaytimeEnemies).Concat(val.OutsideEnemies) select e.enemyType).Where(IsValidEnemyType); foreach (EnemyType item in enumerable) { hashSet.Add(item); } } return hashSet.ToList(); } public static bool IsValidEnemyType(EnemyType enemyType) { if ((Object)(object)enemyType == (Object)null) { return false; } if (string.IsNullOrWhiteSpace(enemyType.enemyName)) { return false; } if ((Object)(object)enemyType.enemyPrefab == (Object)null) { return false; } return true; } } public class EnemyTypeComparer : IEqualityComparer<EnemyType> { public bool Equals(EnemyType x, EnemyType y) { if ((Object)(object)x == (Object)null || (Object)(object)y == (Object)null) { return false; } return x.enemyName == y.enemyName; } public int GetHashCode(EnemyType obj) { return obj.enemyName?.GetHashCode() ?? 0; } } internal static class LevelHelper { public static string CurrentPlanetName { get { if ((Object)(object)StartOfRound.Instance == (Object)null) { Plugin.logger.LogError((object)"Failed to get current planet name. StartOfRound Instance is null."); return string.Empty; } return StartOfRound.Instance.currentLevel.PlanetName; } } public static SelectableLevel GetLevelByName(string planetName) { if ((Object)(object)StartOfRound.Instance == (Object)null) { return null; } SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { if (val.PlanetName == planetName) { return val; } } return null; } public static bool IsCurrentLevel(string planetName) { if ((Object)(object)StartOfRound.Instance == (Object)null) { Plugin.logger.LogError((object)("Failed to check is current level. StartOfRound Instance is null. (PlanetName: " + planetName + ")")); return false; } return StartOfRound.Instance.currentLevel.PlanetName == planetName; } public static List<SpawnableEnemyWithRarity> GetEnemyList(SelectableLevel level, EnemyListType enemyListType) { if ((Object)(object)level == (Object)null) { Plugin.logger.LogError((object)("Failed to get enemy list. SelectableLevel is null. (EnemyListType: " + Utils.GetEnumName(enemyListType) + ")")); return new List<SpawnableEnemyWithRarity>(); } return enemyListType switch { EnemyListType.Inside => level.Enemies, EnemyListType.Outside => level.OutsideEnemies, EnemyListType.Daytime => level.DaytimeEnemies, _ => new List<SpawnableEnemyWithRarity>(), }; } public static bool LevelHasEnemy(string planetName, string enemyName, EnemyListType enemyListType) { int spawnWeight; return LevelHasEnemy(planetName, enemyName, enemyListType, out spawnWeight); } public static bool LevelHasEnemy(string planetName, string enemyName, EnemyListType enemyListType, out int spawnWeight) { spawnWeight = 0; SelectableLevel levelByName = GetLevelByName(planetName); if ((Object)(object)levelBy