using 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
{
}
}