using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using LethalLib.Modules; using Microsoft.CodeAnalysis; using ShadowCat.Configuration; using Unity.Netcode; using UnityEngine; using neoninc.ShadowCat.NetcodePatcher; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("neoninc.ShadowCat")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ShadowCat")] [assembly: AssemblyTitle("neoninc.ShadowCat")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.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; } } } namespace ExampleEnemy { public static class PluginInfo { public const string PLUGIN_GUID = "neoninc.ShadowCat"; public const string PLUGIN_NAME = "ShadowCat"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace ShadowCat { [BepInPlugin("neoninc.shadowcat", "ShadowCat", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static ManualLogSource Logger; public static AssetBundle? ModAssets; internal static PluginConfig BoundConfig { get; private set; } private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; BoundConfig = new PluginConfig(((BaseUnityPlugin)this).Config); InitializeNetworkBehaviours(); string path = "modassets"; ModAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), path)); if ((Object)(object)ModAssets == (Object)null) { Logger.LogError((object)"Failed to load custom assets."); return; } EnemyType val = ModAssets.LoadAsset("ShadowCat"); TerminalNode val2 = ModAssets.LoadAsset("ShadowCatTN"); TerminalKeyword val3 = ModAssets.LoadAsset("ShadowCatTK"); NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab); Enemies.RegisterEnemy(val, BoundConfig.SpawnWeight.Value, (LevelTypes)(-1), val2, val3); Logger.LogInfo((object)"Plugin neoninc.shadowcat is loaded!"); } private static void InitializeNetworkBehaviours() { Type[] types = Assembly.GetExecutingAssembly().GetTypes(); Type[] array = types; foreach (Type type in array) { MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array2 = methods; foreach (MethodInfo methodInfo in array2) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { methodInfo.Invoke(null, null); } } } } } public static class PluginInfo { public const string PLUGIN_GUID = "neoninc.shadowcat"; public const string PLUGIN_NAME = "ShadowCat"; public const string PLUGIN_VERSION = "1.0.0"; } internal class ShadowCatAI : EnemyAI { private enum State { Lurking, Stalking, FleeingLight, Hiding, KillAnimation } [CompilerGenerated] private sealed class d__38 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public ShadowCatAI <>4__this; private Renderer[] 5__1; private float 5__2; private float 5__3; private Renderer[] <>s__4; private int <>s__5; private Renderer 5__6; private Material[] <>s__7; private int <>s__8; private Material 5__9; private float 5__10; private Renderer[] <>s__11; private int <>s__12; private Renderer 5__13; private Material[] <>s__14; private int <>s__15; private Material 5__16; private Color 5__17; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__38(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { 5__1 = null; <>s__4 = null; 5__6 = null; <>s__7 = null; 5__9 = null; <>s__11 = null; 5__13 = null; <>s__14 = null; 5__16 = null; <>1__state = -2; } private bool MoveNext() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(1.5f); <>1__state = 1; return true; case 1: <>1__state = -1; 5__1 = ((Component)<>4__this).GetComponentsInChildren(); <>s__4 = 5__1; for (<>s__5 = 0; <>s__5 < <>s__4.Length; <>s__5++) { 5__6 = <>s__4[<>s__5]; <>s__7 = 5__6.materials; for (<>s__8 = 0; <>s__8 < <>s__7.Length; <>s__8++) { 5__9 = <>s__7[<>s__8]; 5__9.SetFloat("_Mode", 3f); 5__9.SetInt("_SrcBlend", 5); 5__9.SetInt("_DstBlend", 10); 5__9.SetInt("_ZWrite", 0); 5__9.DisableKeyword("_ALPHATEST_ON"); 5__9.EnableKeyword("_ALPHABLEND_ON"); 5__9.DisableKeyword("_ALPHAPREMULTIPLY_ON"); 5__9.renderQueue = 3000; 5__9 = null; } <>s__7 = null; 5__6 = null; } <>s__4 = null; 5__2 = 3f; 5__3 = 0f; break; case 2: <>1__state = -1; break; } if (5__3 < 5__2) { 5__3 += Time.deltaTime; 5__10 = Mathf.Lerp(1f, 0f, 5__3 / 5__2); <>s__11 = 5__1; for (<>s__12 = 0; <>s__12 < <>s__11.Length; <>s__12++) { 5__13 = <>s__11[<>s__12]; <>s__14 = 5__13.materials; for (<>s__15 = 0; <>s__15 < <>s__14.Length; <>s__15++) { 5__16 = <>s__14[<>s__15]; 5__17 = 5__16.color; 5__17.a = 5__10; 5__16.color = 5__17; 5__16 = null; } <>s__14 = null; 5__13 = null; } <>s__11 = null; <>2__current = null; <>1__state = 2; return true; } Object.Destroy((Object)(object)((Component)<>4__this).gameObject); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__37 : IEnumerator, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerControllerB player; public ShadowCatAI <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__37(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (<>4__this.isKillingPlayer) { return false; } <>4__this.isKillingPlayer = true; ((EnemyAI)<>4__this).SwitchToBehaviourClientRpc(4); ((EnemyAI)<>4__this).agent.speed = 0f; ((EnemyAI)<>4__this).inSpecialAnimation = true; ((EnemyAI)<>4__this).SetDestinationToPosition(((Component)player).transform.position, false); <>2__current = (object)new WaitForSeconds(0.2f); <>1__state = 1; return true; case 1: <>1__state = -1; if (((EnemyAI)<>4__this).isEnemyDead) { <>4__this.isKillingPlayer = false; return false; } <>4__this.DoAnimationClientRpc("killPlayer"); <>2__current = (object)new WaitForSeconds(0.5f); <>1__state = 2; return true; case 2: <>1__state = -1; <>4__this.GrabAndKillClientRpc((int)player.playerClientId); <>2__current = (object)new WaitForSeconds(3.5f); <>1__state = 3; return true; case 3: <>1__state = -1; ((EnemyAI)<>4__this).inSpecialAnimation = false; <>4__this.isKillingPlayer = false; <>4__this.inAngerMode = false; <>4__this.angerTimer = 0f; <>4__this.GoHide(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public Transform turnCompass = null; public Transform grabPoint = null; [Header("Shadow Stalker Settings")] public float sneakSpeed = 10f; public float chaseSpeed = 18f; public float detectionRange = 20f; public float senseRange = 4f; public float lightFearRange = 12f; public float retreatCooldown = 40f; public float killAngerTime = 4f; public float minFleeTime = 12f; private float timeSinceHittingPlayer; private float timeSinceSeenFlashlight; private float retreatTimer; private float angerTimer; private float fleeTimer; private bool isKillingPlayer; private bool isDeadAnimationDone; private bool inAngerMode; private bool hasReachedHideSpot; private Vector3 fleeTarget; private bool hasFleeTarget; private Random enemyRandom = null; private void Log(string text) { Plugin.Logger.LogInfo((object)text); } public override void Start() { //IL_0091: Unknown result type (might be due to invalid IL or missing references) ((EnemyAI)this).Start(); Log("ShadowCat spawned."); timeSinceHittingPlayer = 0f; timeSinceSeenFlashlight = 999f; retreatTimer = 0f; angerTimer = 0f; fleeTimer = 0f; isKillingPlayer = false; isDeadAnimationDone = false; inAngerMode = false; hasReachedHideSpot = false; enemyRandom = new Random(StartOfRound.Instance.randomMapSeed + base.thisEnemyIndex); base.currentBehaviourStateIndex = 0; ((EnemyAI)this).StartSearch(((Component)this).transform.position, (AISearchRoutine)null); base.agent.updateRotation = false; } public override void Update() { //IL_0007: 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_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: 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_0037: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) Vector3 velocity = base.agent.velocity; if (((Vector3)(ref velocity)).sqrMagnitude > 0.1f) { velocity = base.agent.velocity; Vector3 normalized = ((Vector3)(ref velocity)).normalized; Quaternion val = Quaternion.LookRotation(normalized); ((Component)this).transform.rotation = Quaternion.RotateTowards(((Component)this).transform.rotation, val, 720f * Time.deltaTime); } ((EnemyAI)this).Update(); if (base.isEnemyDead) { if (isDeadAnimationDone) { return; } isDeadAnimationDone = true; if ((Object)(object)base.creatureVoice != (Object)null) { base.creatureVoice.Stop(); if ((Object)(object)base.dieSFX != (Object)null) { base.creatureVoice.PlayOneShot(base.dieSFX); } } if ((Object)(object)base.creatureAnimator != (Object)null) { base.creatureAnimator.SetTrigger("KillEnemy"); } ((MonoBehaviour)this).StartCoroutine(DissolveAndDestroy()); return; } timeSinceHittingPlayer += Time.deltaTime; timeSinceSeenFlashlight += Time.deltaTime; int currentBehaviourStateIndex = base.currentBehaviourStateIndex; float num = 720f; if ((Object)(object)base.targetPlayer != (Object)null && (currentBehaviourStateIndex == 1 || currentBehaviourStateIndex == 4)) { turnCompass.LookAt(((Component)base.targetPlayer.gameplayCamera).transform.position); ((Component)this).transform.rotation = Quaternion.RotateTowards(((Component)this).transform.rotation, Quaternion.Euler(0f, turnCompass.eulerAngles.y, 0f), num * Time.deltaTime); } if (base.stunNormalizedTimer > 0f) { base.agent.speed = 0f; } if (base.currentBehaviourStateIndex == 1 && (Object)(object)base.targetPlayer != (Object)null && PlayerFlashlightPointsAtUs(base.targetPlayer, lightFearRange)) { fleeTimer = 0f; hasReachedHideSpot = false; hasFleeTarget = false; ((EnemyAI)this).SwitchToBehaviourClientRpc(2); } } public override void DoAIInterval() { //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02b8: 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_0396: Unknown result type (might be due to invalid IL or missing references) ((EnemyAI)this).DoAIInterval(); if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead || isKillingPlayer) { return; } switch (base.currentBehaviourStateIndex) { case 0: base.agent.speed = sneakSpeed; retreatTimer -= base.AIIntervalTime; if (!(retreatTimer > 0f) && FoundClosestPlayerInRange(detectionRange, senseRange)) { Log("Found target, begin stalking."); ((EnemyAI)this).StopSearch(base.currentSearch, true); angerTimer = 0f; ((EnemyAI)this).SwitchToBehaviourClientRpc(1); } break; case 1: { base.agent.speed = sneakSpeed; angerTimer += base.AIIntervalTime; if (!TargetClosestPlayerInAnyCase() || (Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) > 25f && !((EnemyAI)this).CheckLineOfSightForPosition(((Component)base.targetPlayer).transform.position, 45f, 60, -1f, (Transform)null))) { Log("Lost target, going to lurk."); GoHide(); break; } bool flag = PlayerHoldsActiveFlashlight(base.targetPlayer); if (flag) { timeSinceSeenFlashlight = 0f; if (PlayerFlashlightPointsAtUs(base.targetPlayer, lightFearRange)) { Log("Flashlight on us — FLEEING to far end of map!"); fleeTimer = 0f; hasReachedHideSpot = false; ((EnemyAI)this).SwitchToBehaviourClientRpc(2); break; } } if (angerTimer >= killAngerTime && !inAngerMode) { Log("ANGER MODE!"); inAngerMode = true; if ((Object)(object)base.creatureVoice != (Object)null && base.enemyBehaviourStates.Length > 1) { base.creatureVoice.PlayOneShot(base.enemyBehaviourStates[1].VoiceClip); } } StalkBehavior(base.targetPlayer, flag); break; } case 2: base.agent.speed = chaseSpeed; fleeTimer += base.AIIntervalTime; if (!hasFleeTarget) { fleeTarget = GetFleePointFromPlayer(base.targetPlayer); hasFleeTarget = true; ((EnemyAI)this).SetDestinationToPosition(fleeTarget, true); } if (!base.agent.pathPending && base.agent.remainingDistance < 2f) { hasReachedHideSpot = true; hasFleeTarget = false; ((EnemyAI)this).SwitchToBehaviourClientRpc(3); } break; case 3: base.agent.speed = 0f; fleeTimer += base.AIIntervalTime; if (!(fleeTimer < minFleeTime) && !AnyPlayerWithActiveLightNearby(25f)) { Log("No light nearby, resuming hunt."); inAngerMode = false; angerTimer = 0f; fleeTimer = 0f; retreatTimer = 2f; ((EnemyAI)this).StartSearch(((Component)this).transform.position, (AISearchRoutine)null); ((EnemyAI)this).SwitchToBehaviourClientRpc(0); } break; case 4: break; default: Log("Unknown state!"); break; } } private Vector3 GetFarthestPoint() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: 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_00bc: 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_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) Vector3 val = Vector3.zero; int num = 0; for (int i = 0; i < StartOfRound.Instance.connectedPlayersAmount + 1; i++) { PlayerControllerB val2 = StartOfRound.Instance.allPlayerScripts[i]; if ((Object)(object)val2 != (Object)null && !val2.isPlayerDead) { val += ((Component)val2).transform.position; num++; } } if (num == 0) { return ((Component)this).transform.position; } val /= (float)num; Transform val3 = ((EnemyAI)this).ChooseFarthestNodeFromPosition(val, false, 0, false, 50, false); return ((Object)(object)val3 != (Object)null) ? val3.position : ((Component)this).transform.position; } private Vector3 GetFleePointFromPlayer(PlayerControllerB player) { //IL_006a: 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_007a: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null) { return ((Component)this).transform.position; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor((float)(enemyRandom.NextDouble() - 0.5) * 6f, 0f, (float)(enemyRandom.NextDouble() - 0.5) * 6f); Vector3 val2 = ((Component)this).transform.position - ((Component)player).transform.position; Vector3 normalized = ((Vector3)(ref val2)).normalized; Vector3 val3 = ((Component)this).transform.position + val + normalized * 20f; Transform val4 = ((EnemyAI)this).ChooseClosestNodeToPosition(val3, false, 0); if ((Object)(object)val4 != (Object)null) { return val4.position; } return val3; } private void RunToFarthestPointFromAllPlayers() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_00b5: 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_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsOwner) { return; } Vector3 val = Vector3.zero; int num = 0; for (int i = 0; i < StartOfRound.Instance.connectedPlayersAmount + 1; i++) { PlayerControllerB val2 = StartOfRound.Instance.allPlayerScripts[i]; if ((Object)(object)val2 != (Object)null && !val2.isPlayerDead) { val += ((Component)val2).transform.position; num++; } } if (num != 0) { val /= (float)num; Transform val3 = ((EnemyAI)this).ChooseFarthestNodeFromPosition(val, false, 0, false, 50, false); if ((Object)(object)val3 != (Object)null) { ((EnemyAI)this).SetDestinationToPosition(val3.position, false); } } } private bool AnyPlayerWithActiveLightNearby(float range) { //IL_0031: 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) for (int i = 0; i < StartOfRound.Instance.connectedPlayersAmount + 1; i++) { PlayerControllerB val = StartOfRound.Instance.allPlayerScripts[i]; if (!((Object)(object)val == (Object)null) && !val.isPlayerDead && !(Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position) > range) && PlayerHoldsActiveFlashlight(val)) { return true; } } return false; } private bool PlayerHoldsActiveFlashlight(PlayerControllerB player) { if ((Object)(object)player == (Object)null) { return false; } GrabbableObject currentlyHeldObjectServer = player.currentlyHeldObjectServer; if ((Object)(object)currentlyHeldObjectServer == (Object)null) { return false; } FlashlightItem val = (FlashlightItem)(object)((currentlyHeldObjectServer is FlashlightItem) ? currentlyHeldObjectServer : null); if (val != null) { int result; if (((GrabbableObject)val).isBeingUsed) { Battery insertedBattery = currentlyHeldObjectServer.insertedBattery; result = ((insertedBattery != null && insertedBattery.charge > 0f) ? 1 : 0); } else { result = 0; } return (byte)result != 0; } return false; } private bool PlayerFlashlightPointsAtUs(PlayerControllerB player, float range) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) if (!PlayerHoldsActiveFlashlight(player)) { return false; } if (Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position) > range) { return false; } Vector3 val = ((Component)this).transform.position - ((Component)player.gameplayCamera).transform.position; Vector3 normalized = ((Vector3)(ref val)).normalized; Vector3 forward = ((Component)player.gameplayCamera).transform.forward; return Vector3.Angle(forward, normalized) < 50f; } private void StalkBehavior(PlayerControllerB target, bool targetHasFlashlight) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) if (!((NetworkBehaviour)this).IsOwner || (Object)(object)target == (Object)null) { return; } float num = Vector3.Distance(((Component)this).transform.position, ((Component)target).transform.position); if (targetHasFlashlight && !inAngerMode) { Vector3 val = ((Component)target).transform.position - ((Component)target).transform.forward * 8f + new Vector3((float)(enemyRandom.NextDouble() - 0.5) * 3f, 0f, (float)(enemyRandom.NextDouble() - 0.5) * 3f); ((EnemyAI)this).SetDestinationToPosition(val, false); return; } ((EnemyAI)this).SetDestinationToPosition(((Component)target).transform.position, false); if (num < 2.5f && timeSinceHittingPlayer > 1.5f) { Log("Close enough! Starting kill."); ((MonoBehaviour)this).StartCoroutine(KillPlayerAnimation(target)); } } private void GoHide() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) retreatTimer = retreatCooldown; inAngerMode = false; ((EnemyAI)this).StartSearch(((Component)this).transform.position, (AISearchRoutine)null); ((EnemyAI)this).SwitchToBehaviourClientRpc(0); } private bool FoundClosestPlayerInRange(float range, float senseRange) { //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) ((EnemyAI)this).TargetClosestPlayer(1.5f, true, 70f); if ((Object)(object)base.targetPlayer == (Object)null) { ((EnemyAI)this).TargetClosestPlayer(1.5f, false, 70f); range = senseRange; } return (Object)(object)base.targetPlayer != (Object)null && Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) < range; } private bool TargetClosestPlayerInAnyCase() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) base.mostOptimalDistance = 2000f; base.targetPlayer = null; for (int i = 0; i < StartOfRound.Instance.connectedPlayersAmount + 1; i++) { float num = Vector3.Distance(((Component)this).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position); if (num < base.mostOptimalDistance) { base.mostOptimalDistance = num; base.targetPlayer = StartOfRound.Instance.allPlayerScripts[i]; } } return (Object)(object)base.targetPlayer != (Object)null; } [IteratorStateMachine(typeof(d__37))] private IEnumerator KillPlayerAnimation(PlayerControllerB player) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__37(0) { <>4__this = this, player = player }; } [IteratorStateMachine(typeof(d__38))] private IEnumerator DissolveAndDestroy() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__38(0) { <>4__this = this }; } public override void OnCollideWithPlayer(Collider other) { //IL_006e: 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) if (!(timeSinceHittingPlayer < 1f) && !isKillingPlayer) { PlayerControllerB val = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false); if ((Object)(object)val != (Object)null && (inAngerMode || !PlayerHoldsActiveFlashlight(val))) { Log("Collision damage!"); timeSinceHittingPlayer = 0f; val.DamagePlayer(30, true, true, (CauseOfDeath)0, 0, false, default(Vector3)); } if (base.currentBehaviourStateIndex != 2) { } } } public override void HitEnemy(int force = 1, PlayerControllerB? playerWhoHit = null, bool playHitSFX = false, int hitID = -1) { ((EnemyAI)this).HitEnemy(force, playerWhoHit, playHitSFX, hitID); if (!base.isEnemyDead) { if ((Object)(object)base.creatureVoice != (Object)null && base.enemyBehaviourStates.Length != 0 && (Object)(object)base.enemyBehaviourStates[0].VoiceClip != (Object)null) { base.creatureVoice.PlayOneShot(base.enemyBehaviourStates[0].VoiceClip); } base.enemyHP -= force; if (!inAngerMode) { Log("Hit! Anger mode."); inAngerMode = true; angerTimer = killAngerTime; } if (((NetworkBehaviour)this).IsOwner && base.enemyHP <= 0 && !base.isEnemyDead) { ((MonoBehaviour)this).StopCoroutine(base.searchCoroutine); ((EnemyAI)this).KillEnemyOnOwnerClient(false); } } } [ClientRpc] public void DoAnimationClientRpc(string animationName) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) 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(387855304u, val, (RpcDelivery)0); bool flag = animationName != null; ((FastBufferWriter)(ref val2)).WriteValueSafe(ref flag, default(ForPrimitives)); if (flag) { ((FastBufferWriter)(ref val2)).WriteValueSafe(animationName, false); } ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 387855304u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; Log("Animation: " + animationName); base.creatureAnimator.SetTrigger(animationName); } } [ClientRpc] public void GrabAndKillClientRpc(int playerObjectId) { //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) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: 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(626745955u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, playerObjectId); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 626745955u, val, (RpcDelivery)0); } if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { ((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0; Log($"GrabAndKill on player {playerObjectId}"); PlayerControllerB val3 = StartOfRound.Instance.allPlayerScripts[playerObjectId]; if (!((Object)(object)val3 == (Object)null) && !val3.isPlayerDead) { timeSinceHittingPlayer = 0f; val3.inAnimationWithEnemy = (EnemyAI)(object)this; val3.KillPlayer(Vector3.zero, true, (CauseOfDeath)4, 1, default(Vector3)); } } } protected override void __initializeVariables() { ((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 ((NetworkBehaviour)this).__registerRpc(387855304u, new RpcReceiveHandler(__rpc_handler_387855304), "DoAnimationClientRpc"); ((NetworkBehaviour)this).__registerRpc(626745955u, new RpcReceiveHandler(__rpc_handler_626745955), "GrabAndKillClientRpc"); ((EnemyAI)this).__initializeRpcs(); } private static void __rpc_handler_387855304(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_002f: 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_0061: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { bool flag = default(bool); ((FastBufferReader)(ref reader)).ReadValueSafe(ref flag, default(ForPrimitives)); string animationName = null; if (flag) { ((FastBufferReader)(ref reader)).ReadValueSafe(ref animationName, false); } target.__rpc_exec_stage = (__RpcExecStage)1; ((ShadowCatAI)(object)target).DoAnimationClientRpc(animationName); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_626745955(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 playerObjectId = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref playerObjectId); target.__rpc_exec_stage = (__RpcExecStage)1; ((ShadowCatAI)(object)target).GrabAndKillClientRpc(playerObjectId); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "ShadowCatAI"; } } } namespace ShadowCat.Configuration { public class PluginConfig { public ConfigEntry SpawnWeight; public PluginConfig(ConfigFile cfg) { SpawnWeight = cfg.Bind("General", "Spawn weight", 70, "The spawn chance weight for ShadowCat, relative to other existing enemies.\nGoes up from 0, lower is more rare, 100 and up is very common."); ClearUnusedEntries(cfg); } private void ClearUnusedEntries(ConfigFile cfg) { PropertyInfo property = ((object)cfg).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic); Dictionary dictionary = (Dictionary)property.GetValue(cfg, null); dictionary.Clear(); cfg.Save(); } } } namespace __GEN { internal class NetworkVariableSerializationHelper { [RuntimeInitializeOnLoadMethod] internal static void InitializeSerialization() { } } } namespace neoninc.ShadowCat.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }