Decompiled source of YandereCuteamena v1.0.1

BepInEx/plugins/YandereCuteamena/com.github.xuuxiaolan.yanderecuteamena.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using CodeRebirthLib;
using CodeRebirthLib.AssetManagement;
using CodeRebirthLib.ContentManagement;
using CodeRebirthLib.Extensions;
using CodeRebirthLib.Util;
using CodeRebirthLib.Util.Pathfinding;
using GameNetcodeStuff;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using Unity.Netcode.Components;
using UnityEngine;
using UnityEngine.AI;
using UnityEngine.Events;

[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("com.github.xuuxiaolan.yanderecuteamena")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1+984dba320c86fffcba5f3a347cb9f5e484657347")]
[assembly: AssemblyProduct("YandereCuteamena")]
[assembly: AssemblyTitle("com.github.xuuxiaolan.yanderecuteamena")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
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 YandereCuteamena
{
	[RequireComponent(typeof(SmartAgentNavigator))]
	[RequireComponent(typeof(Animator))]
	[RequireComponent(typeof(NetworkAnimator))]
	[RequireComponent(typeof(NetworkTransform))]
	[RequireComponent(typeof(Collider))]
	public abstract class AdvancedEnemyAI : EnemyAI
	{
		internal EnemyAI? targetEnemy;

		internal PlayerControllerB? previousTargetPlayer;

		[Header("Required Components")]
		[SerializeField]
		internal NetworkAnimator creatureNetworkAnimator;

		[SerializeField]
		internal SmartAgentNavigator smartAgentNavigator;

		[Header("Inherited Fields")]
		public AudioClip[] _hitBodySounds = Array.Empty<AudioClip>();

		public AudioClip spawnSound;

		[HideInInspector]
		public Random enemyRandom = new Random();

		public override void Start()
		{
			((EnemyAI)this).Start();
			enemyRandom = new Random(StartOfRound.Instance.randomMapSeed + RoundManager.Instance.SpawnedEnemies.Count + 69);
			if ((Object)(object)spawnSound != (Object)null)
			{
				base.creatureVoice.PlayOneShot(spawnSound);
			}
			smartAgentNavigator.OnUseEntranceTeleport.AddListener((UnityAction<bool>)((EnemyAI)this).SetEnemyOutside);
			smartAgentNavigator.SetAllValues(base.isOutside);
			GrabEnemyRarity(base.enemyType.enemyName);
		}

		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 && playHitSFX && _hitBodySounds.Length != 0)
			{
				base.creatureSFX.PlayOneShot(_hitBodySounds[enemyRandom.Next(_hitBodySounds.Length)]);
			}
		}

		public void GrabEnemyRarity(string enemyName)
		{
			string enemyName2 = enemyName;
			SpawnableEnemyWithRarity val = ((IEnumerable<SpawnableEnemyWithRarity>)RoundManager.Instance.currentLevel.OutsideEnemies).FirstOrDefault((Func<SpawnableEnemyWithRarity, bool>)((SpawnableEnemyWithRarity x) => x.enemyType.enemyName.Equals(enemyName2))) ?? ((IEnumerable<SpawnableEnemyWithRarity>)RoundManager.Instance.currentLevel.DaytimeEnemies).FirstOrDefault((Func<SpawnableEnemyWithRarity, bool>)((SpawnableEnemyWithRarity x) => x.enemyType.enemyName.Equals(enemyName2))) ?? ((IEnumerable<SpawnableEnemyWithRarity>)RoundManager.Instance.currentLevel.Enemies).FirstOrDefault((Func<SpawnableEnemyWithRarity, bool>)((SpawnableEnemyWithRarity x) => x.enemyType.enemyName.Equals(enemyName2)));
			if (val != null)
			{
				YandereCuteamena.Logger.LogDebug((object)(enemyName2 + " has Rarity: " + val.rarity));
			}
			else
			{
				YandereCuteamena.Logger.LogWarning((object)"Enemy not found.");
			}
		}

		public bool FindClosestPlayerInRange(float range, bool targetAlreadyTargettedPerson = true)
		{
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: 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)
			PlayerControllerB val = null;
			float num = float.MaxValue;
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val2 in allPlayerScripts)
			{
				if (((NetworkBehaviour)val2).IsSpawned && val2.isPlayerControlled && !val2.isPlayerDead && !val2.isInHangarShipRoom && EnemyHasLineOfSightToPosition(((Component)val2).transform.position, 60f, range) && !CheckIfPersonAlreadyTargetted(targetAlreadyTargettedPerson, val2))
				{
					float num2 = Vector3.Distance(((Component)this).transform.position, ((Component)val2).transform.position);
					if (num2 < num)
					{
						num = num2;
						val = val2;
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			base.targetPlayer = val;
			return true;
		}

		public bool CheckIfPersonAlreadyTargetted(bool targetAlreadyTargettedPerson, PlayerControllerB playerToCheck)
		{
			if (!targetAlreadyTargettedPerson)
			{
				return false;
			}
			foreach (EnemyAI spawnedEnemy in RoundManager.Instance.SpawnedEnemies)
			{
				if (spawnedEnemy is AdvancedEnemyAI advancedEnemyAI && (Object)(object)((EnemyAI)advancedEnemyAI).targetPlayer == (Object)(object)playerToCheck)
				{
					return true;
				}
			}
			return false;
		}

		public bool EnemyHasLineOfSightToPosition(Vector3 pos, float width = 60f, float range = 20f, float proximityAwareness = 5f)
		{
			//IL_001f: 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_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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: 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)
			Transform val = ((!((Object)(object)base.eye == (Object)null)) ? base.eye : ((Component)this).transform);
			float num = Vector3.Distance(val.position, pos);
			if (num < proximityAwareness)
			{
				return true;
			}
			if (num >= range || Physics.Linecast(val.position, pos, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
			{
				return false;
			}
			Vector3 val2 = pos - val.position;
			return Vector3.Angle(val.forward, val2) < width;
		}

		public bool PlayerLookingAtEnemy(PlayerControllerB player, float dotProductThreshold)
		{
			//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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_005a: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)this).transform.position - ((Component)player).gameObject.transform.position;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			if (Vector3.Dot(((Component)player.gameplayCamera).transform.forward, normalized) < dotProductThreshold)
			{
				return false;
			}
			if (Physics.Linecast(((Component)player.gameplayCamera).transform.position, ((Component)this).transform.position, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
			{
				return false;
			}
			return true;
		}

		public bool EnemySeesPlayer(PlayerControllerB player, float dotThreshold)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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)
			//IL_0039: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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)
			Transform val = ((!((Object)(object)base.eye == (Object)null)) ? ((Component)base.eye).transform : ((Component)this).transform);
			Vector3 val2 = ((Component)player).transform.position - val.position;
			Vector3 normalized = ((Vector3)(ref val2)).normalized;
			if (Vector3.Dot(((Component)this).transform.forward, normalized) < dotThreshold)
			{
				return false;
			}
			float num = Vector3.Distance(val.position, ((Component)player).transform.position);
			if (Physics.Raycast(val.position, normalized, num, StartOfRound.Instance.collidersAndRoomMaskAndDefault, (QueryTriggerInteraction)1))
			{
				return false;
			}
			return true;
		}

		[ServerRpc(RequireOwnership = false)]
		public void SetTargetServerRpc(int PlayerID)
		{
			SetTargetClientRpc(PlayerID);
		}

		[ClientRpc]
		public void SetTargetClientRpc(int PlayerID)
		{
			if (PlayerID == -1)
			{
				base.targetPlayer = null;
				PlayerSetAsTarget(null);
			}
			else if ((Object)(object)StartOfRound.Instance.allPlayerScripts[PlayerID] == (Object)null)
			{
				PlayerSetAsTarget(null);
			}
			else
			{
				previousTargetPlayer = base.targetPlayer;
				base.targetPlayer = StartOfRound.Instance.allPlayerScripts[PlayerID];
				PlayerSetAsTarget(base.targetPlayer);
			}
		}

		[ServerRpc(RequireOwnership = false)]
		public void SetEnemyTargetServerRpc(int enemyID)
		{
			SetEnemyTargetClientRpc(enemyID);
		}

		[ClientRpc]
		public void SetEnemyTargetClientRpc(int enemyID)
		{
			if (enemyID == -1)
			{
				targetEnemy = null;
				EnemySetAsTarget(null);
			}
			else if ((Object)(object)RoundManager.Instance.SpawnedEnemies[enemyID] == (Object)null)
			{
				EnemySetAsTarget(null);
			}
			else
			{
				targetEnemy = RoundManager.Instance.SpawnedEnemies[enemyID];
				EnemySetAsTarget(targetEnemy);
			}
		}

		public virtual void EnemySetAsTarget(EnemyAI? enemy)
		{
		}

		public virtual void PlayerSetAsTarget(PlayerControllerB? player)
		{
		}
	}
	public class CuteamenaEnemyAI : AdvancedEnemyAI
	{
		private enum CuteamenaState
		{
			Searching,
			Passive,
			Jealous,
			Yandere,
			Grief
		}

		private enum AttackType
		{
			Cleaver,
			Headbutt
		}

		[Header("Misc")]
		[SerializeField]
		private InteractTrigger _headPatTrigger;

		[SerializeField]
		private GameObject _cleaverGameObject;

		[Header("Stats")]
		[SerializeField]
		private float _wanderSpeed = 2f;

		[SerializeField]
		private float _followSpeed = 4f;

		[SerializeField]
		private float _chasingSpeed = 6f;

		[SerializeField]
		private int _healAmount = 10;

		[SerializeField]
		private float _healCooldown = 5f;

		[SerializeField]
		private float _attentionDistanceThreshold = 8f;

		[SerializeField]
		private float _jealousAttackRange = 5f;

		[SerializeField]
		private float _detectionRange = 20f;

		[SerializeField]
		private float _doorLockpickInterval = 200f;

		[SerializeField]
		private float _attackInterval = 5f;

		[SerializeField]
		private float _threatFindInterval = 2f;

		[Header("Audio")]
		[SerializeField]
		private AudioSource _griefingSource;

		[SerializeField]
		private AudioClip _cheerUpSound;

		[SerializeField]
		private AudioClip _yandereLaughSound;

		[SerializeField]
		private AudioClip[] _patSounds = Array.Empty<AudioClip>();

		[SerializeField]
		private AudioClip[] _footstepSounds = Array.Empty<AudioClip>();

		private PlayerControllerB? _chasingPlayer;

		private DoorLock? _targetDoor;

		private bool _isCleaverDrawn;

		private float _healTimer;

		private float _doorLockpickTimer;

		private float _attackTimer;

		private float _threatFindTimer;

		private static readonly int RunSpeedFloat = Animator.StringToHash("RunSpeed");

		private static readonly int IsDeadAnimation = Animator.StringToHash("isDead");

		private static readonly int CryingAnimation = Animator.StringToHash("crying");

		private static readonly int HitAnimation = Animator.StringToHash("hit");

		private static readonly int HeadbuttAnimation = Animator.StringToHash("headbutt");

		private static readonly int PetAnimation = Animator.StringToHash("pat");

		private static readonly int PullOutKnifeAnimation = Animator.StringToHash("pullOutKnife");

		private static readonly int SlashAnimation = Animator.StringToHash("slashAttack");

		public override void Start()
		{
			base.Start();
			((UnityEvent<PlayerControllerB>)(object)_headPatTrigger.onInteract).AddListener((UnityAction<PlayerControllerB>)OnHeadPatInteract);
			smartAgentNavigator.StartSearchRoutine(40f);
			((EnemyAI)this).agent.speed = _wanderSpeed;
			_healTimer = _healCooldown;
		}

		public override void Update()
		{
			((EnemyAI)this).Update();
			_headPatTrigger.interactable = ((EnemyAI)this).currentBehaviourStateIndex == 1 || ((EnemyAI)this).currentBehaviourStateIndex == 2;
			if (!((EnemyAI)this).isEnemyDead && ((NetworkBehaviour)this).IsServer)
			{
				_healTimer -= Time.deltaTime;
				_doorLockpickTimer -= Time.deltaTime;
				_attackTimer -= Time.deltaTime;
			}
		}

		public override void DoAIInterval()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).DoAIInterval();
			if (!((EnemyAI)this).isEnemyDead && !StartOfRound.Instance.allPlayersDead)
			{
				Animator creatureAnimator = ((EnemyAI)this).creatureAnimator;
				int runSpeedFloat = RunSpeedFloat;
				Vector3 velocity = ((EnemyAI)this).agent.velocity;
				creatureAnimator.SetFloat(runSpeedFloat, ((Vector3)(ref velocity)).magnitude / 3f);
				switch (((EnemyAI)this).currentBehaviourStateIndex)
				{
				case 0:
					LookForSenpai();
					break;
				case 1:
					DoPassiveBehavior();
					break;
				case 2:
					DoJealousBehavior();
					break;
				case 3:
					DoYandereBehavior();
					break;
				case 4:
					DoGriefBehavior();
					break;
				}
			}
		}

		private void LookForSenpai()
		{
			//IL_0029: 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)
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (!val.isPlayerDead && val.isPlayerControlled && Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position) < _detectionRange)
				{
					((EnemyAI)this).agent.speed = _followSpeed;
					SetTargetServerRpc(Array.IndexOf(StartOfRound.Instance.allPlayerScripts, val));
					((EnemyAI)this).SwitchToBehaviourServerRpc(1);
					break;
				}
			}
		}

		private void DoPassiveBehavior()
		{
			//IL_0187: 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)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: 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_009a: 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)
			if ((Object)(object)((EnemyAI)this).targetPlayer == (Object)null || ((EnemyAI)this).targetPlayer.isPlayerDead)
			{
				((EnemyAI)this).agent.speed = 0f;
				((EnemyAI)this).creatureAnimator.SetBool(CryingAnimation, true);
				((EnemyAI)this).SwitchToBehaviourServerRpc(4);
				return;
			}
			if ((Object)(object)targetEnemy != (Object)null)
			{
				if (targetEnemy.isEnemyDead)
				{
					SetEnemyTargetServerRpc(-1);
					return;
				}
				smartAgentNavigator.DoPathingToDestination(((Component)targetEnemy).transform.position);
				if (!(_attackTimer > 0f) && Vector3.Distance(((Component)this).transform.position, ((Component)targetEnemy).transform.position) < 2f)
				{
					_attackTimer = _attackInterval;
					creatureNetworkAnimator.SetTrigger(HeadbuttAnimation, true);
				}
				return;
			}
			if ((Object)(object)_targetDoor != (Object)null && _doorLockpickTimer <= 0f)
			{
				smartAgentNavigator.DoPathingToDestination(RoundManager.Instance.GetRandomNavMeshPositionInRadius(((Component)_targetDoor).transform.position, 2f, default(NavMeshHit)));
				if (Vector3.Distance(((Component)this).transform.position, ((Component)_targetDoor).transform.position) < ((EnemyAI)this).agent.stoppingDistance)
				{
					creatureNetworkAnimator.SetTrigger(HeadbuttAnimation, true);
					_doorLockpickTimer = _doorLockpickInterval;
				}
				return;
			}
			smartAgentNavigator.DoPathingToDestination(((Component)((EnemyAI)this).targetPlayer).transform.position);
			if (_healTimer <= 0f && ((EnemyAI)this).targetPlayer.health < 100)
			{
				HealSenpai();
				_healTimer = _healCooldown;
			}
			else if (_threatFindTimer <= 0f)
			{
				FindThreatsNearbySenpai();
				_threatFindTimer = _threatFindInterval;
			}
			else if (_doorLockpickTimer <= 0f)
			{
				ChooseDoorToLockpick();
				_doorLockpickTimer = _doorLockpickInterval;
			}
			else if (IsSenpaiIgnoringMe() || IsSenpaiWithOtherPlayers())
			{
				((EnemyAI)this).SwitchToBehaviourServerRpc(2);
			}
		}

		private void DoJealousBehavior()
		{
			if ((Object)(object)((EnemyAI)this).targetPlayer == (Object)null || ((EnemyAI)this).targetPlayer.isPlayerDead)
			{
				((EnemyAI)this).agent.speed = 0f;
				((EnemyAI)this).creatureAnimator.SetBool(CryingAnimation, true);
				((EnemyAI)this).SwitchToBehaviourServerRpc(4);
				return;
			}
			FollowSenpaiForwardly();
			float distanceToRival;
			PlayerControllerB val = LookForOtherPlayers(out distanceToRival);
			if ((Object)(object)val != (Object)null)
			{
				AttackPlayer(val, distanceToRival);
			}
			else if (HasBeenFurtherIgnored())
			{
				creatureNetworkAnimator.SetTrigger(PullOutKnifeAnimation, true);
				((EnemyAI)this).agent.speed = _chasingSpeed;
				((EnemyAI)this).SwitchToBehaviourServerRpc(3);
			}
		}

		private void DoYandereBehavior()
		{
			//IL_004f: 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)
			if (!_isCleaverDrawn)
			{
				return;
			}
			if ((Object)(object)_chasingPlayer == (Object)null)
			{
				float num = float.MaxValue;
				PlayerControllerB chasingPlayer = null;
				PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
				foreach (PlayerControllerB val in allPlayerScripts)
				{
					if (val.isPlayerControlled && !val.isPlayerDead)
					{
						chasingPlayer = val;
						num = Mathf.Min(num, Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position));
					}
				}
				if (num <= _detectionRange)
				{
					_chasingPlayer = chasingPlayer;
				}
			}
			else if (_chasingPlayer.isPlayerDead)
			{
				_chasingPlayer = null;
			}
			ChaseAndAttackPlayer(_chasingPlayer);
		}

		private void DoGriefBehavior()
		{
			if (HasSenpaiBodyBeenMoved())
			{
				creatureNetworkAnimator.SetTrigger(PullOutKnifeAnimation, true);
				((EnemyAI)this).agent.speed = _chasingSpeed;
				((EnemyAI)this).creatureAnimator.SetBool(CryingAnimation, false);
				((EnemyAI)this).SwitchToBehaviourServerRpc(3);
			}
		}

		private void OnHeadPatInteract(PlayerControllerB player)
		{
			if (!((Object)(object)player == (Object)null) && !((Object)(object)player != (Object)(object)((EnemyAI)this).targetPlayer))
			{
				HeadPatServerRpc(PlayerControllerReference.op_Implicit(player));
			}
		}

		[ServerRpc(RequireOwnership = false)]
		private void HeadPatServerRpc(PlayerControllerReference playerControllerReference)
		{
			PlayerControllerB val = PlayerControllerReference.op_Implicit(playerControllerReference);
			creatureNetworkAnimator.SetTrigger(PetAnimation, true);
			if (((EnemyAI)this).currentBehaviourStateIndex == 2 && !((Object)(object)val != (Object)(object)((EnemyAI)this).targetPlayer))
			{
				((EnemyAI)this).SwitchToBehaviourClientRpc(1);
			}
		}

		private void ChaseAndAttackPlayer(PlayerControllerB? player)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)player == (Object)null))
			{
				smartAgentNavigator.DoPathingToDestination(((Component)player).transform.position);
				if (Vector3.Distance(((Component)this).transform.position, ((Component)player).transform.position) < 2f)
				{
					creatureNetworkAnimator.SetTrigger(SlashAnimation, true);
				}
			}
		}

		private void FollowSenpaiForwardly()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: 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)
			Vector3 val = ((Component)((EnemyAI)this).targetPlayer).transform.position + ((Component)((EnemyAI)this).targetPlayer).transform.forward * 2f;
			smartAgentNavigator.DoPathingToDestination(val);
		}

		private void HealSenpai()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).targetPlayer.DamagePlayerFromOtherClientServerRpc(-_healAmount, ((Component)this).transform.position, Array.IndexOf(StartOfRound.Instance.allPlayerScripts, ((EnemyAI)this).targetPlayer));
		}

		private void FindThreatsNearbySenpai()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(((Component)((EnemyAI)this).targetPlayer).transform.position, 10f, LayerMask.GetMask(new string[1] { "Enemies" }), (QueryTriggerInteraction)2);
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				EnemyAICollisionDetect component = ((Component)val).GetComponent<EnemyAICollisionDetect>();
				if (!((Object)(object)component == (Object)null) && component.mainScript.enemyType.canDie && !component.mainScript.isEnemyDead && !((Object)(object)component.mainScript.enemyType == (Object)(object)((EnemyAI)this).enemyType))
				{
					SetEnemyTargetServerRpc(RoundManager.Instance.SpawnedEnemies.IndexOf(component.mainScript));
					break;
				}
			}
		}

		private void ChooseDoorToLockpick()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = Physics.OverlapSphere(((Component)this).transform.position, 10f, LayerMask.GetMask(new string[1] { "InteractableObject" }), (QueryTriggerInteraction)2);
			Collider[] array2 = array;
			foreach (Collider val in array2)
			{
				DoorLock component = ((Component)val).GetComponent<DoorLock>();
				if ((Object)(object)component != (Object)null && component.isLocked)
				{
					((Component)component).gameObject.GetComponent<NavMeshObstacle>().carving = false;
					_targetDoor = component;
					break;
				}
			}
		}

		private bool IsSenpaiIgnoringMe()
		{
			//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)
			if (Vector3.Distance(((Component)this).transform.position, ((Component)((EnemyAI)this).targetPlayer).transform.position) > _attentionDistanceThreshold)
			{
				return !PlayerLookingAtEnemy(((EnemyAI)this).targetPlayer, 0.2f);
			}
			return false;
		}

		private bool IsSenpaiWithOtherPlayers()
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (!((Object)(object)val == (Object)(object)((EnemyAI)this).targetPlayer) && !val.isPlayerDead && !(Vector3.Distance(((Component)((EnemyAI)this).targetPlayer).transform.position, ((Component)val).transform.position) > 5f))
				{
					return true;
				}
			}
			return false;
		}

		private PlayerControllerB? LookForOtherPlayers(out float distanceToRival)
		{
			//IL_003f: 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)
			distanceToRival = 0f;
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			foreach (PlayerControllerB val in allPlayerScripts)
			{
				if (!((Object)(object)val == (Object)(object)((EnemyAI)this).targetPlayer) && !val.isPlayerDead && val.isPlayerControlled)
				{
					distanceToRival = Vector3.Distance(((Component)this).transform.position, ((Component)val).transform.position);
					if (!(distanceToRival > _jealousAttackRange + 5f) && !IsSenpaiLookingAt(val))
					{
						return val;
					}
				}
			}
			return null;
		}

		private bool IsSenpaiLookingAt(PlayerControllerB player)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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)
			//IL_002d: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((Component)player).transform.position - ((Component)((EnemyAI)this).targetPlayer.gameplayCamera).transform.position;
			Vector3 normalized = ((Vector3)(ref val)).normalized;
			float num = Vector3.Dot(((Component)((EnemyAI)this).targetPlayer.gameplayCamera).transform.forward, normalized);
			return num > 0.7f;
		}

		private bool HasBeenFurtherIgnored()
		{
			return Random.Range(0, 1000) < 2;
		}

		private void AttackPlayer(PlayerControllerB player, float distanceToRival)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			smartAgentNavigator.DoPathingToDestination(((Component)player).transform.position);
			if (!(distanceToRival < ((EnemyAI)this).agent.stoppingDistance + _jealousAttackRange))
			{
				creatureNetworkAnimator.SetTrigger(HeadbuttAnimation, true);
			}
		}

		private void AttackPlayerWithAttackType(PlayerControllerB player, AttackType attackType)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			switch (attackType)
			{
			case AttackType.Cleaver:
				player.DamagePlayer(20, true, false, (CauseOfDeath)1, 0, false, ((Component)this).transform.forward * 10f);
				break;
			case AttackType.Headbutt:
				player.DamagePlayer(10, true, false, (CauseOfDeath)1, 0, false, ((Component)this).transform.forward * 10f);
				break;
			}
		}

		private bool HasSenpaiBodyBeenMoved()
		{
			if ((Object)(object)((EnemyAI)this).targetPlayer.deadBody == (Object)null)
			{
				return false;
			}
			DeadBodyInfo deadBody = ((EnemyAI)this).targetPlayer.deadBody;
			if (deadBody.grabBodyObject.isHeld)
			{
				return true;
			}
			return deadBody.bodyMovedThisFrame;
		}

		public void StartPatAnimEvent()
		{
			smartAgentNavigator.cantMove = true;
			smartAgentNavigator.StopAgent();
		}

		public void EndPatAnimEvent()
		{
			smartAgentNavigator.cantMove = false;
		}

		public void StartGriefingAnimEvent()
		{
			_ = _griefingSource.isPlaying;
		}

		public void FootstepSoundAnimEvent()
		{
			((EnemyAI)this).creatureSFX.PlayOneShot(_footstepSounds[enemyRandom.Next(_footstepSounds.Length)]);
		}

		public void DrawMeatCleaverAnimEvent()
		{
			_isCleaverDrawn = true;
			_cleaverGameObject.SetActive(true);
		}

		public void DropCleaverAnimEvent()
		{
		}

		public void OnSwingCleaverAnimEvent()
		{
			if (!((Object)(object)_chasingPlayer == (Object)null))
			{
				AttackPlayerWithAttackType(_chasingPlayer, AttackType.Cleaver);
			}
		}

		public void HeadbuttAnimEvent()
		{
			if ((Object)(object)_targetDoor != (Object)null)
			{
				_targetDoor.UnlockDoor();
				((Component)_targetDoor).gameObject.GetComponent<NavMeshObstacle>().carving = true;
				_targetDoor = null;
			}
			else if ((Object)(object)_chasingPlayer != (Object)null)
			{
				AttackPlayerWithAttackType(_chasingPlayer, AttackType.Headbutt);
			}
		}

		public override void HitEnemy(int force = 1, PlayerControllerB? playerWhoHit = null, bool playHitSFX = false, int hitID = -1)
		{
			base.HitEnemy(force, playerWhoHit, playHitSFX, hitID);
			if (((EnemyAI)this).isEnemyDead)
			{
				return;
			}
			((EnemyAI)this).enemyHP = ((EnemyAI)this).enemyHP - force;
			if (((EnemyAI)this).enemyHP <= 0)
			{
				if (((NetworkBehaviour)this).IsOwner)
				{
					((EnemyAI)this).KillEnemyOnOwnerClient(false);
				}
				return;
			}
			if (((NetworkBehaviour)this).IsServer)
			{
				creatureNetworkAnimator.SetTrigger(HitAnimation, true);
			}
			if (!((Object)(object)playerWhoHit == (Object)null) && ((EnemyAI)this).currentBehaviourStateIndex != 3)
			{
				if (((EnemyAI)this).currentBehaviourStateIndex == 2)
				{
					creatureNetworkAnimator.SetTrigger(PullOutKnifeAnimation, true);
					((EnemyAI)this).agent.speed = _chasingSpeed;
					((EnemyAI)this).SwitchToBehaviourStateOnLocalClient(3);
				}
				else
				{
					((EnemyAI)this).SwitchToBehaviourStateOnLocalClient(2);
				}
			}
		}

		public override void KillEnemy(bool destroy = false)
		{
			((EnemyAI)this).KillEnemy(destroy);
			_cleaverGameObject.SetActive(false);
			if (((NetworkBehaviour)this).IsServer)
			{
				((EnemyAI)this).creatureAnimator.SetBool(IsDeadAnimation, true);
			}
		}
	}
	[BepInPlugin("com.github.xuuxiaolan.yanderecuteamena", "YandereCuteamena", "1.0.1")]
	public class YandereCuteamena : BaseUnityPlugin
	{
		internal static ManualLogSource Logger { get; private set; }

		public static CRMod Mod { get; private set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			NetcodePatcher();
			AssetBundle val = CRLib.LoadBundle(Assembly.GetExecutingAssembly(), "yanderecuteamenaassets");
			Mod = CRLib.RegisterMod((BaseUnityPlugin)(object)this, val);
			Mod.RegisterContentHandlers();
			Logger.LogInfo((object)"com.github.xuuxiaolan.yanderecuteamena v1.0.1 has loaded!");
		}

		private void NetcodePatcher()
		{
			IEnumerable<Type> loadableTypes = AssemblyExtensions.GetLoadableTypes(Assembly.GetExecutingAssembly());
			foreach (Type item in loadableTypes)
			{
				MethodInfo[] methods = item.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array = methods;
				foreach (MethodInfo methodInfo in array)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}
	}
	public class CuteamenaHandler : ContentHandler<CuteamenaHandler>
	{
		public class CuteamenaBundle : AssetBundleLoader<CuteamenaBundle>
		{
			public CuteamenaBundle(CRMod mod, string filePath)
				: base(mod, filePath)
			{
			}
		}

		public CuteamenaHandler(CRMod mod)
			: base(mod)
		{
			CuteamenaBundle cuteamenaBundle = default(CuteamenaBundle);
			if (((ContentHandler)this).TryLoadContentBundle<CuteamenaBundle>("cuteaassets", ref cuteamenaBundle))
			{
				((ContentHandler)this).LoadAllContent<CuteamenaBundle>(cuteamenaBundle);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.github.xuuxiaolan.yanderecuteamena";

		public const string PLUGIN_NAME = "YandereCuteamena";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}