Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of VoodooEnemy v2.1.0
Bepinex/plugins/VoodooEnemy/VoodooEnemy.dll
Decompiled 2 years agousing System; using System.Collections; 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.Logging; using GameNetcodeStuff; using LethalLib.Modules; using Microsoft.CodeAnalysis; using Unity.Netcode; using UnityEngine; using VoodooEnemy.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("VoodooEnemy")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("There's a fucking ghost on your screen, and you can't get it off!")] [assembly: AssemblyFileVersion("2.1.0.0")] [assembly: AssemblyInformationalVersion("2.1.0")] [assembly: AssemblyProduct("VoodooEnemy")] [assembly: AssemblyTitle("VoodooEnemy")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] internal class <Module> { static <Module>() { } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 VoodooEnemy { [BepInPlugin("VoodooEnemy", "VoodooEnemy", "2.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public static EnemyType VoodooEnemy; internal static ManualLogSource Logger; public static AudioClip[] teleAudio = (AudioClip[])(object)new AudioClip[1]; public static AudioClip[] chaseAudioMorning = (AudioClip[])(object)new AudioClip[1]; public static AudioClip[] chaseAudioNoon = (AudioClip[])(object)new AudioClip[1]; public static AudioClip[] chaseAudioNight = (AudioClip[])(object)new AudioClip[1]; public static AudioClip voodooFootsteps = new AudioClip(); private void Awake() { Logger = ((BaseUnityPlugin)this).Logger; Assets.PopulateAssets(); VoodooEnemy = Assets.MainAssetBundle.LoadAsset<EnemyType>("VoodooEnemy"); TerminalNode val = Assets.MainAssetBundle.LoadAsset<TerminalNode>("VoodooEnemyTN"); TerminalKeyword val2 = Assets.MainAssetBundle.LoadAsset<TerminalKeyword>("VoodooEnemyTK"); teleAudio[0] = Assets.MainAssetBundle.LoadAsset<AudioClip>("sfx_telep"); chaseAudioMorning[0] = Assets.MainAssetBundle.LoadAsset<AudioClip>("telep_calm"); chaseAudioNoon[0] = Assets.MainAssetBundle.LoadAsset<AudioClip>("telep_irritated"); chaseAudioNight[0] = Assets.MainAssetBundle.LoadAsset<AudioClip>("telep_aggro"); voodooFootsteps = Assets.MainAssetBundle.LoadAsset<AudioClip>("voodoo footsteps"); NetworkPrefabs.RegisterNetworkPrefab(VoodooEnemy.enemyPrefab); Enemies.RegisterEnemy(VoodooEnemy, 35, (LevelTypes)(-1), (SpawnType)0, val, val2); Logger.LogInfo((object)"Plugin VoodooEnemy is loaded!"); 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 Assets { public static AssetBundle MainAssetBundle; public static void PopulateAssets() { string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); MainAssetBundle = AssetBundle.LoadFromFile(Path.Combine(directoryName, "modassets")); if ((Object)(object)MainAssetBundle == (Object)null) { Plugin.Logger.LogError((object)"Failed to load custom assets."); } } } internal class VoodooEnemyAI : EnemyAI { public enum AudioPlaying { None, Morning, Noon, Night } private enum State { WaitingForPlayer, ChasingPlayer, LookingForPlayer } public Transform turnCompass; public Transform attackArea; public GameObject voodooBody; public GameObject booshBody; private Vector3 spawnPosition; private Vector3 spawnRotation; private float secondsSinceLastSawPlayer; private bool currentlyTeleporting; private Vector3 destinationPos; private float audioFade; private Random ventRand; public AudioPlaying currentAudio = AudioPlaying.None; public override void Start() { //IL_0017: 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) ((EnemyAI)this).Start(); booshBody.SetActive(false); spawnPosition = base.serverPosition; spawnRotation = base.serverRotation; Plugin.Logger.LogInfo((object)((object)(Vector3)(ref spawnPosition)).ToString()); ((EnemyAI)this).SetClientCalculatingAI(true); currentAudio = AudioPlaying.None; audioFade = 0f; base.currentBehaviourStateIndex = 0; base.creatureSFX.clip = Plugin.voodooFootsteps; base.agent.speed = 6f; base.agent.acceleration = 0f; ventRand = new Random(StartOfRound.Instance.randomMapSeed + base.thisEnemyIndex); int num = ventRand.Next(1, 101); if (num == 69) { voodooBody.SetActive(false); booshBody.SetActive(true); } } public override void Update() { ((EnemyAI)this).Update(); switch (base.currentBehaviourStateIndex) { case 0: secondsSinceLastSawPlayer += Time.deltaTime; break; case 2: secondsSinceLastSawPlayer += Time.deltaTime; break; } float timeSinceRoundStarted = StartOfRound.Instance.timeSinceRoundStarted; float num = timeSinceRoundStarted; if (!(num < 200f)) { if (!(num < 380f)) { if (num > 380f && currentAudio != AudioPlaying.Night) { currentAudio = AudioPlaying.Night; } } else if (currentAudio != AudioPlaying.Noon) { currentAudio = AudioPlaying.Noon; } } else if (currentAudio != AudioPlaying.Morning) { currentAudio = AudioPlaying.Morning; } } public override void DoAIInterval() { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) ((EnemyAI)this).DoAIInterval(); if (((EnemyAI)this).TargetClosestPlayer(0.5f, true, 260f)) { secondsSinceLastSawPlayer = 0f; if (base.currentBehaviourStateIndex != 1 && base.targetPlayer.HasLineOfSightToPosition(((Component)this).transform.position, 70f, 25, -1f)) { if (base.currentBehaviourStateIndex == 0) { } GameNetworkManager.Instance.localPlayerController.JumpToFearLevel(0.7f, true); ((EnemyAI)this).SwitchToBehaviourClientRpc(1); base.creatureSFX.Play(); ((MonoBehaviour)this).StartCoroutine(AccelerationDuringChase()); } destinationPos = ((Component)base.targetPlayer).transform.position; ((EnemyAI)this).SetDestinationToPosition(destinationPos, false); ((EnemyAI)this).SetMovingTowardsTargetPlayer(base.targetPlayer); } else { PlayerControllerB targetPlayer = base.targetPlayer; base.targetPlayer = ((EnemyAI)this).GetClosestPlayer(false, false, false); if ((Object)(object)base.targetPlayer == (Object)null) { secondsSinceLastSawPlayer = 0f; if (base.currentBehaviourStateIndex != 0) { ((EnemyAI)this).SwitchToBehaviourClientRpc(0); } ((EnemyAI)this).SetMovingTowardsTargetPlayer((PlayerControllerB)null); ((EnemyAI)this).SetDestinationToPosition(spawnPosition, false); return; } if (((NetworkBehaviour)this).OwnerClientId != base.targetPlayer.actualClientId) { ((EnemyAI)this).ChangeOwnershipOfEnemy(base.targetPlayer.actualClientId); } if (base.currentBehaviourStateIndex == 1) { ((EnemyAI)this).SwitchToBehaviourClientRpc(2); } if (secondsSinceLastSawPlayer > 3f) { if (base.currentBehaviourStateIndex != 0) { ((EnemyAI)this).SwitchToBehaviourClientRpc(0); } ((EnemyAI)this).SetDestinationToPosition(spawnPosition, false); if (Mathf.Abs(Vector3.Distance(((Component)this).transform.position, spawnPosition)) < 3f) { base.agent.acceleration = 0f; base.creatureSFX.Stop(); } if (secondsSinceLastSawPlayer > (float)ventRand.Next(30, 60)) { TeleportVoodooToCloseVent(); } } if (((EnemyAI)this).TargetClosestPlayer(0.5f, false, 360f) && base.currentBehaviourStateIndex == 0) { ((Component)this).transform.LookAt(((Component)base.targetPlayer).transform.position); } } ((EnemyAI)this).SyncPositionToClients(); } public override void OnCollideWithPlayer(Collider other) { PlayerControllerB val = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false); if ((Object)(object)val != (Object)null && !currentlyTeleporting) { TeleportPlayerToRandomPos(val); } } public void TeleportPlayerToRandomPos(PlayerControllerB player) { //IL_0031: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_0062: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) currentlyTeleporting = true; Random random = new Random(); Vector3 position = RoundManager.Instance.insideAINodes[random.Next(0, RoundManager.Instance.insideAINodes.Length)].transform.position; while (Vector3.Distance(position, ((Component)this).transform.position) < 30f) { position = RoundManager.Instance.insideAINodes[random.Next(0, RoundManager.Instance.insideAINodes.Length)].transform.position; } player.DropAllHeldItemsAndSync(); player.TeleportPlayer(position, false, 0f, false, true); Plugin.Logger.LogInfo((object)"voodoo attempted to teleport player"); player.DamagePlayer(20, true, true, (CauseOfDeath)0, 0, false, default(Vector3)); player.SpawnPlayerAnimation(); if (player.statusEffectAudio.isPlaying) { player.statusEffectAudio.Stop(); player.statusEffectAudio.clip = null; } RoundManager.PlayRandomClip(player.statusEffectAudio, Plugin.teleAudio, false, 1f, 0); currentlyTeleporting = false; } public void TeleportVoodooToCloseVent() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) float[] array = new float[RoundManager.Instance.allEnemyVents.Length]; EnemyVent[] array2 = (EnemyVent[])(object)new EnemyVent[RoundManager.Instance.allEnemyVents.Length]; for (int i = 0; i < RoundManager.Instance.allEnemyVents.Length; i++) { float num = Vector3.Distance(((Component)RoundManager.Instance.allEnemyVents[i]).transform.position, ((Component)base.targetPlayer).transform.position); array[i] = num; array2[i] = RoundManager.Instance.allEnemyVents[i]; } Array.Sort(array, array2); for (int j = 0; j < array.Length; j++) { if (array[j] > 20f) { ((Component)this).transform.position = ((Component)array2[j]).transform.position; ((EnemyAI)this).SyncPositionToClients(); secondsSinceLastSawPlayer = 0f; spawnPosition = ((Component)array2[j]).transform.position; break; } } Plugin.Logger.LogInfo((object)("Teleported Voodoo closer to player " + ((object)base.targetPlayer).ToString())); } public IEnumerator AccelerationDuringChase() { yield return (object)new WaitForSeconds(0.5f); base.agent.acceleration = 2.5f; yield return (object)new WaitForSeconds(3f); base.agent.acceleration = 9999f; } public void VoodooSoundHandler(AudioPlaying currentAudio) { switch (currentAudio) { case AudioPlaying.Morning: base.targetPlayer.statusEffectAudio.clip = Plugin.chaseAudioMorning[0]; ((MonoBehaviour)this).StartCoroutine(FadeAudio(base.targetPlayer.statusEffectAudio)); break; case AudioPlaying.Noon: base.targetPlayer.statusEffectAudio.clip = Plugin.chaseAudioNoon[0]; ((MonoBehaviour)this).StartCoroutine(FadeAudio(base.targetPlayer.statusEffectAudio)); break; case AudioPlaying.Night: base.targetPlayer.statusEffectAudio.clip = Plugin.chaseAudioNight[0]; ((MonoBehaviour)this).StartCoroutine(FadeAudio(base.targetPlayer.statusEffectAudio)); break; } } private IEnumerator FadeAudio(AudioSource audioSource) { if (audioSource.isPlaying) { while (audioSource.volume > 0f) { yield return (object)new WaitForSeconds(0.025f); audioSource.volume -= 0.025f; } audioSource.Stop(); audioSource.clip = null; } else { audioSource.Play(); while (audioSource.volume < 1f) { yield return (object)new WaitForSeconds(0.025f); audioSource.volume += 0.025f; } } } protected override void __initializeVariables() { ((EnemyAI)this).__initializeVariables(); } protected internal override string __getTypeName() { return "VoodooEnemyAI"; } } public static class PluginInfo { public const string PLUGIN_GUID = "VoodooEnemy"; public const string PLUGIN_NAME = "VoodooEnemy"; public const string PLUGIN_VERSION = "2.1.0"; } } namespace VoodooEnemy.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }