Decompiled source of DiddyEnemy v1.0.2

plugins/DiddyEnemy/Capitanull.DiddyEnemy.dll

Decompiled a year ago
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 Capitanull.DiddyEnemy.NetcodePatcher;
using DiddyEnemy.Configuration;
using GameNetcodeStuff;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[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("Capitanull.DiddyEnemy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.2.0")]
[assembly: AssemblyInformationalVersion("1.0.2")]
[assembly: AssemblyProduct("DiddyEnemy")]
[assembly: AssemblyTitle("Capitanull.DiddyEnemy")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.2.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.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 DiddyEnemy
{
	internal class DiddyEnemyAI : EnemyAI
	{
		private enum State
		{
			SearchingForPlayer,
			Enraged,
			ThePhaseOfTheDiddler
		}

		public Transform turnCompass;

		public Transform attackArea;

		private float timeSinceHittingLocalPlayer;

		private float timeSinceNewRandPos;

		private Vector3 positionRandomness;

		private Vector3 StalkPos;

		private Random enemyRandom;

		private static AudioClip? voiceILoveThisGameFull;

		private static AudioClip? voiceAintNoParty;

		private static AudioClip? voiceItsReallyNice;

		private static AudioClip? voiceGameChanger;

		private static AudioClip? voice_Passionate;

		private static AudioClip? voice_DifferentParty;

		private static AudioClip? voice_ItsGonnaTakeAllOfUs;

		private static AudioClip? voice_MyCulture;

		private bool ambientalsoundenabled = true;

		private AudioClip[] ambientalSoundsIndex;

		private bool isAmbientalSoundCoroutineRunning;

		private bool isDeadAnimationDone;

		private bool isCoroutineRunning;

		private float stage;

		private bool isHit;

		private bool alreadyEnraged;

		private bool becomeEnraged;

		private bool isWalk;

		private bool isRunning;

		private bool isIdle;

		private bool isEnraging;

		private bool alreadyfoundNode;

		public Transform diddylocation;

		private PlayerControllerB playerController;

		private bool isCarryingPlayer;

		private Vector3 mainEntrancePosition;

		private Vector3? lastKnownPlayerPosition;

		private float timeSinceLastSeen;

		private float memoryDuration = 5f;

		private Dictionary<PlayerControllerB, int> playerRecognitionLevels = new Dictionary<PlayerControllerB, int>();

		private Dictionary<PlayerControllerB, int> playergrabbedonce = new Dictionary<PlayerControllerB, int>();

		private bool recognition;

		private bool chasing;

		private bool alreadycounting;

		private Vector3 sensedPlayerPosition;

		private bool holding;

		private float walk = 3f;

		private float run = 8f;

		private bool spawnedInRunning;

		private Vector3 lastPlayerPosition;

		private float timeInSameRadius;

		private float radiusThreshold = 5f;

		private float catchTimeout = 2f;

		public override void Start()
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: 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)
			((EnemyAI)this).Start();
			voiceILoveThisGameFull = Plugin.Voice_ILOVETHISGAMEFULL;
			voiceAintNoParty = Plugin.Voice_AintNoPartyLikeADiddyParty;
			voiceItsReallyNice = Plugin.Voice_ItsReallyNice;
			voiceGameChanger = Plugin.Voice_GameChanger;
			voice_Passionate = Plugin.Voice_Passionate;
			voice_DifferentParty = Plugin.Voice_DifferentParty;
			voice_ItsGonnaTakeAllOfUs = Plugin.Voice_ItsGonnaTakeAllOfUs;
			voice_MyCulture = Plugin.Voice_MyCulture;
			ambientalSoundsIndex = (AudioClip[])(object)new AudioClip[4] { voice_Passionate, voice_DifferentParty, voice_ItsGonnaTakeAllOfUs, voice_MyCulture };
			int count = NetworkManager.Singleton.ConnectedClients.Count;
			timeSinceHittingLocalPlayer = 0f;
			timeSinceNewRandPos = 0f;
			positionRandomness = new Vector3(0f, 0f, 0f);
			enemyRandom = new Random(StartOfRound.Instance.randomMapSeed + base.thisEnemyIndex);
			isDeadAnimationDone = false;
			mainEntrancePosition = RoundManager.FindMainEntrancePosition(false, false);
			base.agent.autoBraking = false;
			base.agent.stoppingDistance = 0f;
			base.agent.angularSpeed = 5000f;
			base.agent.autoRepath = true;
			base.enemyHP = ((count <= 1) ? 5 : 7);
			((MonoBehaviour)this).StartCoroutine(SpawnIn());
		}

		public override void Update()
		{
			//IL_00cc: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Update();
			if (base.isEnemyDead)
			{
				if (!isDeadAnimationDone)
				{
					isDeadAnimationDone = true;
					((MonoBehaviour)this).StopCoroutine(GrabPlayer());
					if (isCarryingPlayer)
					{
						DropPlayer();
					}
					ambientalsoundenabled = false;
					((MonoBehaviour)this).StopCoroutine(AmbientalSounds());
					ambientalsoundenabled = false;
					base.creatureVoice.Stop();
					base.creatureVoice.PlayOneShot(base.dieSFX);
					DoAnimationClientRpc("KillEnemy");
				}
				return;
			}
			int currentBehaviourStateIndex = base.currentBehaviourStateIndex;
			timeSinceHittingLocalPlayer += Time.deltaTime;
			timeSinceNewRandPos += Time.deltaTime;
			if ((Object)(object)base.targetPlayer != (Object)null && currentBehaviourStateIndex == 1)
			{
				turnCompass.LookAt(((Component)base.targetPlayer.gameplayCamera).transform.position);
				((Component)this).transform.rotation = Quaternion.Lerp(((Component)this).transform.rotation, Quaternion.Euler(new Vector3(0f, turnCompass.eulerAngles.y, 0f)), 4f * Time.deltaTime);
			}
			if (base.stunNormalizedTimer == 0.1f)
			{
				base.agent.speed = walk;
				isCarryingPlayer = false;
				stage = 1f;
				((EnemyAI)this).SwitchToBehaviourClientRpc(0);
				becomeEnraged = false;
				isEnraging = false;
			}
			if (base.stunNormalizedTimer > 0f)
			{
				base.agent.speed = 0f;
				if (isCarryingPlayer)
				{
					isCarryingPlayer = false;
					((MonoBehaviour)this).StopCoroutine(GrabPlayer());
					DropPlayer();
				}
			}
		}

		public override void DoAIInterval()
		{
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).DoAIInterval();
			if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead)
			{
				return;
			}
			switch (base.currentBehaviourStateIndex)
			{
			case 0:
				if (!((NetworkBehaviour)this).IsSpawned)
				{
					break;
				}
				if (FoundClosestPlayerInRange(15f, 15f) && (Object)(object)base.targetPlayer != (Object)null)
				{
					((MonoBehaviour)this).StartCoroutine(RandomChanceToAttack());
				}
				if (FoundClosestPlayerInRange(25f, 3f) && (Object)(object)base.targetPlayer != (Object)null)
				{
					if (playerRecognitionLevels.ContainsKey(base.targetPlayer) && playerRecognitionLevels[base.targetPlayer] >= 2 && !isDeadAnimationDone)
					{
						recognition = true;
						chasing = true;
						((MonoBehaviour)this).StopCoroutine(AmbientalSounds());
						((EnemyAI)this).SwitchToBehaviourClientRpc(1);
					}
					else
					{
						recognition = false;
						chasing = false;
					}
				}
				else
				{
					recognition = false;
					chasing = false;
				}
				break;
			case 1:
				if (!TargetClosestPlayerInAnyCase() || (Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) > 20f && !((EnemyAI)this).CheckLineOfSightForPosition(((Component)base.targetPlayer).transform.position, 45f, 60, -1f, (Transform)null)))
				{
					((MonoBehaviour)this).StartCoroutine(SpawnIn());
				}
				else
				{
					Enraged();
				}
				break;
			case 2:
			{
				((Behaviour)base.agent).enabled = true;
				base.agent.speed = 12f;
				((Component)playerController).transform.SetParent(((Component)this).transform);
				Vector3 localPosition = default(Vector3);
				((Vector3)(ref localPosition))..ctor(0f, 0.5f, 1f);
				((Component)playerController).transform.localPosition = localPosition;
				playerController.fallValue = 0f;
				playerController.fallValueUncapped = 0f;
				playerController.isGroundedOnServer = true;
				if (playerController.isPlayerDead || base.targetPlayer.isPlayerDead)
				{
					DropPlayer();
					((MonoBehaviour)this).StartCoroutine(SpawnIn());
				}
				if (!alreadyfoundNode)
				{
					FindFurthestNode();
				}
				break;
			}
			default:
				Plugin.Logger.LogInfo((object)"This Behavior State doesn't exist!");
				break;
			}
		}

		private bool FoundClosestPlayerInRange(float range, float senseRange)
		{
			//IL_009c: 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_00ab: 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_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			timeSinceLastSeen += Time.deltaTime;
			if (timeSinceLastSeen >= memoryDuration)
			{
				lastKnownPlayerPosition = null;
				chasing = false;
				((EnemyAI)this).SwitchToBehaviourClientRpc(0);
				return false;
			}
			((EnemyAI)this).TargetClosestPlayer(2f, true, 70f);
			if ((Object)(object)base.targetPlayer != (Object)null && chasing)
			{
				lastKnownPlayerPosition = ((Component)base.targetPlayer).transform.position;
				timeSinceLastSeen = 0f;
			}
			else if (lastKnownPlayerPosition.HasValue)
			{
				Vector2 val = Random.insideUnitCircle * 1f;
				Vector3 val2 = new Vector3(val.x, 0f, val.y) + lastKnownPlayerPosition.Value;
				((EnemyAI)this).SetDestinationToPosition(val2, false);
				if (Vector3.Distance(((Component)this).transform.position, lastKnownPlayerPosition.Value) < 1f)
				{
					lastKnownPlayerPosition = null;
					chasing = false;
					((EnemyAI)this).SwitchToBehaviourClientRpc(0);
					return false;
				}
			}
			if ((Object)(object)base.targetPlayer == (Object)null)
			{
				((EnemyAI)this).TargetClosestPlayer(2f, false, 70f);
				range = senseRange;
			}
			if ((Object)(object)base.targetPlayer != (Object)null)
			{
				return Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) < range;
			}
			return false;
		}

		private bool TargetClosestPlayerInAnyCase()
		{
			//IL_001d: 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)
			base.mostOptimalDistance = 2000f;
			base.targetPlayer = null;
			for (int i = 0; i < StartOfRound.Instance.connectedPlayersAmount + 1; i++)
			{
				base.tempDist = Vector3.Distance(((Component)this).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position);
				if (base.tempDist < base.mostOptimalDistance)
				{
					base.mostOptimalDistance = base.tempDist;
					base.targetPlayer = StartOfRound.Instance.allPlayerScripts[i];
				}
			}
			if ((Object)(object)base.targetPlayer == (Object)null)
			{
				return false;
			}
			return true;
		}

		private void Enraged()
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			int currentBehaviourStateIndex = base.currentBehaviourStateIndex;
			if (recognition && !becomeEnraged)
			{
				chasing = true;
				becomeEnraged = false;
				stage = 2f;
				base.agent.speed = run;
				alreadyEnraged = true;
				base.creatureVoice.Stop();
				base.creatureVoice.PlayOneShot(voiceAintNoParty);
				((MonoBehaviour)this).StopCoroutine(AmbientalSounds());
				recognition = false;
			}
			if ((Object)(object)base.targetPlayer == (Object)null || !((NetworkBehaviour)this).IsOwner)
			{
				return;
			}
			FacePlayerDirectly();
			if (currentBehaviourStateIndex == 1)
			{
				if (isCarryingPlayer)
				{
					((MonoBehaviour)this).StopCoroutine(AmbientalSounds());
					((EnemyAI)this).SwitchToBehaviourClientRpc(2);
				}
				if ((Object)(object)base.targetPlayer != (Object)null)
				{
					((EnemyAI)this).SetDestinationToPosition(((Component)base.targetPlayer).transform.position, true);
				}
			}
		}

		private void FacePlayerDirectly()
		{
			//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)
			//IL_002e: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: 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_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: 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_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			float num = Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position);
			if (num < radiusThreshold)
			{
				if (Vector3.Distance(lastPlayerPosition, ((Component)base.targetPlayer).transform.position) < 0.5f)
				{
					timeInSameRadius += Time.deltaTime;
				}
				else
				{
					timeInSameRadius = 0f;
				}
				if (timeInSameRadius >= catchTimeout)
				{
					Vector3 val = ((Component)base.targetPlayer).transform.position - ((Component)this).transform.position;
					Vector3 normalized = ((Vector3)(ref val)).normalized;
					Quaternion rotation = Quaternion.LookRotation(new Vector3(normalized.x, 0f, normalized.z));
					((Component)this).transform.rotation = rotation;
					timeInSameRadius = 0f;
				}
			}
			else
			{
				timeInSameRadius = 0f;
			}
			lastPlayerPosition = ((Component)base.targetPlayer).transform.position;
		}

		private IEnumerator BecomeEnraged()
		{
			((MonoBehaviour)this).StopCoroutine(RandomChanceToAttack());
			alreadyEnraged = false;
			becomeEnraged = true;
			ambientalsoundenabled = false;
			((MonoBehaviour)this).StopCoroutine(AmbientalSounds());
			base.creatureVoice.Stop();
			base.creatureVoice.PlayOneShot(voiceILoveThisGameFull);
			base.agent.speed = 0f;
			((Behaviour)base.agent).enabled = false;
			stage = 2f;
			yield return (object)new WaitForSeconds(3.5f);
			((Behaviour)base.agent).enabled = true;
			base.agent.speed = run;
			alreadyEnraged = true;
			becomeEnraged = false;
			((EnemyAI)this).SwitchToBehaviourClientRpc(1);
			((MonoBehaviour)this).StopCoroutine(BecomeEnraged());
		}

		private IEnumerator SpawnIn()
		{
			if (!spawnedInRunning)
			{
				spawnedInRunning = true;
				if (!base.creatureAnimator.GetBool("spawnDone"))
				{
					base.agent.speed = 0f;
					((Behaviour)base.agent).enabled = false;
					yield return (object)new WaitForSeconds(3.2f);
					((Behaviour)base.agent).enabled = true;
					base.creatureAnimator.SetBoolString("spawnDone", true);
					((MonoBehaviour)this).StartCoroutine(HandleMovementAndAnimation());
				}
				isCarryingPlayer = false;
				holding = false;
				alreadyfoundNode = false;
				recognition = false;
				chasing = false;
				isEnraging = false;
				becomeEnraged = false;
				alreadyEnraged = false;
				ambientalsoundenabled = true;
				stage = 1f;
				base.agent.speed = walk;
				((MonoBehaviour)this).StartCoroutine(AmbientalSounds());
				base.creatureVoice.Stop();
				base.creatureVoice.PlayOneShot(voiceItsReallyNice);
				((EnemyAI)this).StartSearch(((Component)this).transform.position, (AISearchRoutine)null);
				base.currentBehaviourStateIndex = 0;
				spawnedInRunning = false;
				((MonoBehaviour)this).StopCoroutine(SpawnIn());
			}
		}

		private IEnumerator HandleMovementAndAnimation()
		{
			Vector3 previousPosition = ((Component)this).transform.position;
			while (!base.isEnemyDead && !isDeadAnimationDone)
			{
				yield return (object)new WaitForSeconds(0.2f);
				Vector3 val = ((Component)this).transform.position - previousPosition;
				float magnitude = ((Vector3)(ref val)).magnitude;
				float num = magnitude / 0.2f;
				if (isHit)
				{
					HitState();
					yield return (object)new WaitForSeconds(0.17f);
				}
				else if (stage == 1f)
				{
					if (num >= 1f && !isWalk && !base.isEnemyDead)
					{
						EnterWalkState();
						isWalk = true;
						isIdle = false;
						isRunning = false;
						isEnraging = false;
					}
					else if (num < 1f && !isIdle && !isEnraging && !becomeEnraged && !base.isEnemyDead)
					{
						EnterIdleState();
						isWalk = false;
						isIdle = true;
						isRunning = false;
						isEnraging = false;
					}
				}
				else if (stage == 2f)
				{
					if (alreadyEnraged && !becomeEnraged && num >= 1f && !isRunning && !base.isEnemyDead)
					{
						EnterRunState();
						isWalk = false;
						isRunning = true;
						isIdle = false;
						isEnraging = false;
					}
					else if (num < 1f && !isIdle && !isEnraging && !becomeEnraged && !base.isEnemyDead)
					{
						EnterIdleState();
						isWalk = false;
						isIdle = true;
						isRunning = false;
						isEnraging = false;
					}
					else if (becomeEnraged && !isEnraging && !base.isEnemyDead)
					{
						EnterEnragingState();
						isWalk = false;
						isRunning = false;
						isIdle = false;
					}
				}
				if (stage == 0f && !isCoroutineRunning && !base.isEnemyDead)
				{
					yield return ((MonoBehaviour)this).StartCoroutine(SpawnIn());
				}
				previousPosition = ((Component)this).transform.position;
			}
			if (base.isEnemyDead)
			{
				DoAnimationClientRpc("KillEnemy");
			}
			((MonoBehaviour)this).StopCoroutine(HandleMovementAndAnimation());
		}

		private void EnterIdleState()
		{
			DoAnimationClientRpc("idle");
		}

		private void EnterWalkState()
		{
			DoAnimationClientRpc("startWalk");
		}

		private void EnterRunState()
		{
			DoAnimationClientRpc("startRun");
		}

		private void EnterEnragingState()
		{
			if (!isEnraging)
			{
				DoAnimationClientRpc("enragedStart");
				isEnraging = true;
			}
		}

		private void HitState()
		{
			if (isHit)
			{
				isHit = false;
				DoAnimationClientRpc("hit");
			}
		}

		private void FindFurthestNode()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			if (!alreadyfoundNode)
			{
				((EnemyAI)this).SetDestinationToPosition(mainEntrancePosition, true);
				alreadyfoundNode = true;
			}
		}

		public override void OnCollideWithPlayer(Collider other)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			int currentBehaviourStateIndex = base.currentBehaviourStateIndex;
			if (timeSinceHittingLocalPlayer < 1f || becomeEnraged)
			{
				return;
			}
			PlayerControllerB val = (playerController = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false));
			if ((Object)(object)val != (Object)null && !isCarryingPlayer)
			{
				timeSinceHittingLocalPlayer = 0f;
				val.DamagePlayer(20, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
				if (currentBehaviourStateIndex == 1 && !becomeEnraged && !base.isEnemyDead && !isEnraging)
				{
					((EnemyAI)this).SwitchToBehaviourClientRpc(2);
					isCarryingPlayer = true;
					((MonoBehaviour)this).StartCoroutine(GrabPlayer());
					FindFurthestNode();
				}
			}
		}

		public override void HitEnemy(int force = 1, PlayerControllerB? playerWhoHit = null, bool playHitSFX = true, int hitID = -1)
		{
			((EnemyAI)this).HitEnemy(force, playerWhoHit, playHitSFX, hitID);
			int currentBehaviourStateIndex = base.currentBehaviourStateIndex;
			if (base.isEnemyDead || !((NetworkBehaviour)this).IsSpawned || isEnraging || !base.creatureAnimator.GetBool("spawnDone"))
			{
				return;
			}
			base.enemyHP -= force;
			if (((NetworkBehaviour)this).IsOwner && base.enemyHP <= 0 && !base.isEnemyDead)
			{
				((MonoBehaviour)this).StopCoroutine(base.searchCoroutine);
				((EnemyAI)this).KillEnemyOnOwnerClient(false);
				((MonoBehaviour)this).StopCoroutine(AmbientalSounds());
			}
			if (base.isEnemyDead)
			{
				return;
			}
			if (currentBehaviourStateIndex != 0)
			{
				ambientalsoundenabled = false;
				((MonoBehaviour)this).StopCoroutine(AmbientalSounds());
			}
			if ((Object)(object)playerWhoHit != (Object)null && !isDeadAnimationDone)
			{
				if (playerRecognitionLevels.ContainsKey(playerWhoHit))
				{
					playerRecognitionLevels[playerWhoHit]++;
				}
				else
				{
					playerRecognitionLevels[playerWhoHit] = 1;
				}
			}
			if (currentBehaviourStateIndex == 0 && !base.isEnemyDead && !isEnraging)
			{
				((MonoBehaviour)this).StartCoroutine(BecomeEnraged());
			}
			if (currentBehaviourStateIndex == 2 && isCarryingPlayer && base.enemyHP >= 1)
			{
				DropPlayer();
				((MonoBehaviour)this).StartCoroutine(BecomeEnraged());
			}
		}

		private void DropPlayer()
		{
			if ((Object)(object)playerController != (Object)null)
			{
				if (playerController.isPlayerDead || base.isEnemyDead || isCarryingPlayer)
				{
					((MonoBehaviour)this).StopCoroutine(GrabPlayer());
					playerController.jumpForce = 13f;
					((Component)playerController).transform.SetParent((Transform)null);
					playerController.disableLookInput = false;
					playerController.disableLookInput = false;
					((MonoBehaviour)this).StartCoroutine(SpawnIn());
				}
			}
			else
			{
				Plugin.Logger.LogInfo((object)"Can't drop");
			}
		}

		private IEnumerator GrabPlayer()
		{
			if (holding)
			{
				yield break;
			}
			holding = true;
			if ((Object)(object)playerController != (Object)null)
			{
				Vector3 localPosition = default(Vector3);
				while (isCarryingPlayer && !playerController.isPlayerDead)
				{
					playerController.jumpForce = 0f;
					playerController.DropAllHeldItemsAndSync();
					playerController.isHoldingObject = false;
					if (!playergrabbedonce.ContainsKey(playerController))
					{
						playergrabbedonce[playerController] = 0;
					}
					((Component)playerController).transform.SetParent(((Component)this).transform);
					((Vector3)(ref localPosition))..ctor(0f, 0.5f, 0.7f);
					((Component)playerController).transform.localPosition = localPosition;
					timeSinceHittingLocalPlayer = 0f;
					if (playerController.hasBeenCriticallyInjured && playergrabbedonce[playerController] == 0)
					{
						playergrabbedonce[playerController]++;
						DropPlayer();
					}
					else if (playerController.hasBeenCriticallyInjured && playergrabbedonce[playerController] > 0)
					{
						playerController.DamagePlayer(20, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
					}
					else if (!playerController.hasBeenCriticallyInjured)
					{
						playerController.DamagePlayer(20, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
					}
					yield return (object)new WaitForSeconds(1f);
				}
			}
			holding = false;
			((MonoBehaviour)this).StopCoroutine(GrabPlayer());
		}

		private IEnumerator AmbientalSounds()
		{
			if (isAmbientalSoundCoroutineRunning)
			{
				yield break;
			}
			isAmbientalSoundCoroutineRunning = true;
			ambientalsoundenabled = true;
			int num = -1;
			while (ambientalsoundenabled)
			{
				int randomIndex;
				do
				{
					randomIndex = Random.Range(0, ambientalSoundsIndex.Length);
				}
				while (randomIndex == num && ambientalSoundsIndex.Length > 1);
				float num2 = Random.Range(20, 35);
				yield return (object)new WaitForSeconds(num2);
				if (ambientalsoundenabled)
				{
					base.creatureVoice.PlayOneShot(ambientalSoundsIndex[randomIndex]);
				}
				num = randomIndex;
			}
			isAmbientalSoundCoroutineRunning = false;
		}

		private IEnumerator RandomChanceToAttack()
		{
			if (!alreadycounting)
			{
				alreadycounting = true;
				yield return (object)new WaitForSeconds(5f);
				int num = Random.Range(0, 10);
				if (num == 9)
				{
					((MonoBehaviour)this).StartCoroutine(BecomeEnraged());
					alreadycounting = false;
					yield break;
				}
				yield return (object)new WaitForSeconds(1f);
				alreadycounting = false;
			}
			((MonoBehaviour)this).StopCoroutine(RandomChanceToAttack());
		}

		[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_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 != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(3603108156u, val, (RpcDelivery)0);
				bool flag = animationName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(animationName, false);
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 3603108156u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				base.creatureAnimator.SetTrigger(animationName);
			}
		}

		protected override void __initializeVariables()
		{
			((EnemyAI)this).__initializeVariables();
		}

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_DiddyEnemyAI()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(3603108156u, new RpcReceiveHandler(__rpc_handler_3603108156));
		}

		private static void __rpc_handler_3603108156(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<bool>(ref flag, default(ForPrimitives));
				string animationName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref animationName, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((DiddyEnemyAI)(object)target).DoAnimationClientRpc(animationName);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "DiddyEnemyAI";
		}
	}
	[BepInPlugin("Capitanull.DiddyEnemy", "DiddyEnemy", "1.0.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		public static AssetBundle? ModAssets;

		public static AudioClip? Voice_ILOVETHISGAMEFULL;

		public static AudioClip? Voice_AintNoPartyLikeADiddyParty;

		public static AudioClip? Voice_ItsReallyNice;

		public static AudioClip? Voice_GameChanger;

		public static AudioClip? Voice_Passionate;

		public static AudioClip? Voice_DifferentParty;

		public static AudioClip? Voice_ItsGonnaTakeAllOfUs;

		public static AudioClip? Voice_MyCulture;

		internal static PluginConfig BoundConfig { get; private set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			BoundConfig = new PluginConfig(((BaseUnityPlugin)this).Config);
			InitializeNetworkBehaviours();
			string path = "diddyassets";
			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;
			}
			Voice_ILOVETHISGAMEFULL = ModAssets.LoadAsset<AudioClip>("Voice_ILOVETHISGAMEFULL");
			Voice_AintNoPartyLikeADiddyParty = ModAssets.LoadAsset<AudioClip>("Voice_AintNoPartyLikeADiddyParty");
			Voice_ItsReallyNice = ModAssets.LoadAsset<AudioClip>("Voice_ItsReallyNice");
			Voice_GameChanger = ModAssets.LoadAsset<AudioClip>("Voice_NowINeedYouToListenToThisGameChanger");
			Voice_Passionate = ModAssets.LoadAsset<AudioClip>("Voice_WeArePasssionate");
			Voice_DifferentParty = ModAssets.LoadAsset<AudioClip>("Voice_DifferentTypeOfParty");
			Voice_ItsGonnaTakeAllOfUs = ModAssets.LoadAsset<AudioClip>("Voice_ItsGonnaTakeAllOfUs");
			Voice_MyCulture = ModAssets.LoadAsset<AudioClip>("Voice_MyGoalUsedTobe");
			EnemyType val = ModAssets.LoadAsset<EnemyType>("DiddyEnemy");
			TerminalNode val2 = ModAssets.LoadAsset<TerminalNode>("DiddyEnemyTN");
			TerminalKeyword val3 = ModAssets.LoadAsset<TerminalKeyword>("DiddyEnemyTK");
			Dictionary<LevelTypes, int> dictionary = new Dictionary<LevelTypes, int>
			{
				{
					(LevelTypes)4,
					BoundConfig.SpawnWeight_ExperimentationLevel.Value
				},
				{
					(LevelTypes)8,
					BoundConfig.SpawnWeight_AssuranceLevel.Value
				},
				{
					(LevelTypes)16,
					BoundConfig.SpawnWeight_VowLevel.Value
				},
				{
					(LevelTypes)32,
					BoundConfig.SpawnWeight_OffenseLevel.Value
				},
				{
					(LevelTypes)64,
					BoundConfig.SpawnWeight_MarchLevel.Value
				},
				{
					(LevelTypes)128,
					BoundConfig.SpawnWeight_RendLevel.Value
				},
				{
					(LevelTypes)256,
					BoundConfig.SpawnWeight_DineLevel.Value
				},
				{
					(LevelTypes)512,
					BoundConfig.SpawnWeight_TitanLevel.Value
				},
				{
					(LevelTypes)(-1),
					10
				},
				{
					(LevelTypes)1024,
					BoundConfig.SpawnWeight_Modded.Value
				}
			};
			Dictionary<string, int> dictionary2 = new Dictionary<string, int>();
			NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab);
			Enemies.RegisterEnemy(val, dictionary, dictionary2, val2, val3);
			Logger.LogInfo((object)"Plugin Capitanull.DiddyEnemy 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 = "Capitanull.DiddyEnemy";

		public const string PLUGIN_NAME = "DiddyEnemy";

		public const string PLUGIN_VERSION = "1.0.2";
	}
}
namespace DiddyEnemy.Configuration
{
	public class PluginConfig
	{
		public ConfigEntry<int> SpawnWeight_ExperimentationLevel;

		public ConfigEntry<int> SpawnWeight_AssuranceLevel;

		public ConfigEntry<int> SpawnWeight_VowLevel;

		public ConfigEntry<int> SpawnWeight_OffenseLevel;

		public ConfigEntry<int> SpawnWeight_MarchLevel;

		public ConfigEntry<int> SpawnWeight_RendLevel;

		public ConfigEntry<int> SpawnWeight_DineLevel;

		public ConfigEntry<int> SpawnWeight_TitanLevel;

		public ConfigEntry<int> SpawnWeight_Modded;

		public PluginConfig(ConfigFile cfg)
		{
			SpawnWeight_ExperimentationLevel = cfg.Bind<int>("General", "Spawn weight ExperimentationLevel", 5, "The spawn chance weight for DiddyEnemy, relative to other existing enemies. Goes up from 0, lower is more rare, 100 and up is very common.");
			SpawnWeight_AssuranceLevel = cfg.Bind<int>("General", "Spawn weight AssuranceLevel", 5, (ConfigDescription)null);
			SpawnWeight_VowLevel = cfg.Bind<int>("General", "Spawn weight VowLevel", 5, (ConfigDescription)null);
			SpawnWeight_OffenseLevel = cfg.Bind<int>("General", "Spawn weight OffenseLevel", 5, (ConfigDescription)null);
			SpawnWeight_MarchLevel = cfg.Bind<int>("General", "Spawn weight MarchLevel", 5, (ConfigDescription)null);
			SpawnWeight_RendLevel = cfg.Bind<int>("General", "Spawn weight RendLevel", 5, (ConfigDescription)null);
			SpawnWeight_DineLevel = cfg.Bind<int>("General", "Spawn weight DineLevel", 5, (ConfigDescription)null);
			SpawnWeight_TitanLevel = cfg.Bind<int>("General", "Spawn weight TitanLevel", 5, (ConfigDescription)null);
			SpawnWeight_Modded = cfg.Bind<int>("General", "Spawn weight Modded Levels", 5, "The spawn chance for Diddy on all custom maps added");
			ClearUnusedEntries(cfg);
		}

		private void ClearUnusedEntries(ConfigFile cfg)
		{
			PropertyInfo property = ((object)cfg).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic);
			Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)property.GetValue(cfg, null);
			dictionary.Clear();
			cfg.Save();
		}
	}
}
namespace Capitanull.DiddyEnemy.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}