Decompiled source of CaptainClark v1.0.0

plugins/CaptainClark/CaptainClark.dll

Decompiled 10 hours 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 CaptainClark.Configuration;
using CaptainClark.NetcodePatcher;
using GameNetcodeStuff;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.AI;

[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("CaptainClark")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CaptainClark")]
[assembly: AssemblyTitle("CaptainClark")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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 CaptainClark
{
	internal class BorrowedSounds
	{
		private const int DogGrowlState = 1;

		private const int DogLungeState = 3;

		public AudioClip? Breathing;

		public AudioClip? Growl;

		public AudioClip? Roar;

		public AudioClip? Lunge;

		public AudioClip? Bite;

		public AudioClip? Chew;

		public AudioClip? Death;

		public AudioClip[] Hurt = (AudioClip[])(object)new AudioClip[0];

		public AudioClip[] Footsteps = (AudioClip[])(object)new AudioClip[0];

		private static BorrowedSounds? found;

		public static BorrowedSounds Get()
		{
			if (found != null)
			{
				return found;
			}
			MouthDogAI val = null;
			CrawlerAI val2 = null;
			EnemyType[] array = Resources.FindObjectsOfTypeAll<EnemyType>();
			foreach (EnemyType val3 in array)
			{
				if (!((Object)(object)val3.enemyPrefab == (Object)null))
				{
					if ((Object)(object)val == (Object)null)
					{
						val = val3.enemyPrefab.GetComponent<MouthDogAI>();
					}
					if ((Object)(object)val2 == (Object)null)
					{
						val2 = val3.enemyPrefab.GetComponent<CrawlerAI>();
					}
				}
			}
			BorrowedSounds borrowedSounds = new BorrowedSounds();
			if ((Object)(object)val != (Object)null)
			{
				borrowedSounds.Breathing = val.breathingSFX;
				borrowedSounds.Roar = val.screamSFX;
				if (((EnemyAI)val).enemyBehaviourStates.Length > 3)
				{
					borrowedSounds.Growl = ((EnemyAI)val).enemyBehaviourStates[1].VoiceClip;
					borrowedSounds.Lunge = ((EnemyAI)val).enemyBehaviourStates[3].SFXClip;
				}
				PlayAudioAnimationEvent[] componentsInChildren = ((Component)val).GetComponentsInChildren<PlayAudioAnimationEvent>(true);
				foreach (PlayAudioAnimationEvent val4 in componentsInChildren)
				{
					if (val4.randomClips != null && val4.randomClips.Length != 0)
					{
						borrowedSounds.Footsteps = val4.randomClips;
						break;
					}
				}
			}
			if ((Object)(object)val2 != (Object)null)
			{
				borrowedSounds.Bite = val2.bitePlayerSFX;
				borrowedSounds.Chew = val2.eatPlayerSFX;
				borrowedSounds.Death = ((EnemyAI)val2).dieSFX;
				if (val2.hitCrawlerSFX != null)
				{
					borrowedSounds.Hurt = val2.hitCrawlerSFX;
				}
			}
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
			{
				Plugin.Logger.LogWarning((object)"Could not find the Eyeless Dog or the Thumper to borrow sounds from. Captain Clark will be missing some of his.");
				return borrowedSounds;
			}
			found = borrowedSounds;
			return borrowedSounds;
		}
	}
	internal class CaptainClarkAI : EnemyAI
	{
		private enum State
		{
			Roaming,
			Chasing,
			Attacking
		}

		public Transform turnCompass;

		public Transform attackArea;

		private const float RoamSpeed = 2.2f;

		private const float ChaseSpeed = 4.6f;

		private const float CrawlSpeed = 3f;

		private const float SightRange = 30f;

		private const float SenseRange = 4f;

		private const float LoseTargetTime = 6f;

		private const float NavMeshSearchRadius = 15f;

		private const int MaxHP = 15;

		private const int CrawlBelowHP = 3;

		private const int ShovelForce = 1;

		private const int NoWeaponID = -1;

		private const float ModelHeight = 1.7f;

		private const float AttackReach = 1.33f;

		private const float BiteHoldDistance = 0.67f;

		private static readonly Vector3 BodyHoldPosition = new Vector3(0f, 1.3f, 0.41f);

		private const float PlayerHeight = 2.6f;

		private const float NeckHeight = 0.85f;

		private const float AttackCooldown = 1.5f;

		private const int BiteHealthThreshold = 60;

		private const int SwipeDamage = 40;

		private const float FirstSwipeTime = 0.7f;

		private const float SecondSwipeTime = 1.13f;

		private const float SwipeEndTime = 1.6f;

		private const float BiteTime = 2.7f;

		private const float BodyDropTime = 3.25f;

		private const float BiteEndTime = 4.17f;

		private const int CrawlContactDamage = 20;

		private const float CrawlContactInterval = 1f;

		private const float CrawlColliderHeight = 0.37f;

		private const float CrawlColliderLength = 1.1f;

		private static readonly float[] WalkStepPhases = new float[2] { 0.05f, 0.65f };

		private static readonly float[] RunStepPhases = new float[2] { 0.15f, 0.62f };

		private const float FootstepVolume = 0.6f;

		private static readonly int MovingParameter = Animator.StringToHash("moving");

		private static readonly int ChasingParameter = Animator.StringToHash("chasing");

		private static readonly int CrawlingParameter = Animator.StringToHash("crawling");

		private static readonly int WalkState = Animator.StringToHash("Walk");

		private static readonly int RunState = Animator.StringToHash("Run");

		private readonly AISearchRoutine roamSearch = new AISearchRoutine();

		private readonly HashSet<int> animatorParameters = new HashSet<int>();

		private Transform biteHoldPoint;

		private Transform bodyHoldPoint;

		private BoxCollider? hitCollider;

		private Vector3 standingColliderSize;

		private Vector3 standingColliderCenter;

		private Coroutine? swipeCoroutine;

		private Coroutine? biteCoroutine;

		private DeadBodyInfo? heldBody;

		private bool crawling;

		private float attackRange;

		private float lastSawTargetTime;

		private float lastAttackTime;

		private float timeSinceContactDamage;

		private Vector3 previousPosition;

		private float smoothedSpeed;

		private BorrowedSounds sounds;

		private int voiceState = -1;

		private int footstepState;

		private float footstepCycleTime;

		private bool IsGrabbingPlayer
		{
			get
			{
				if (biteCoroutine != null)
				{
					return (Object)(object)base.inSpecialAnimationWithPlayer != (Object)null;
				}
				return false;
			}
		}

		[Conditional("DEBUG")]
		private void LogIfDebugBuild(string text)
		{
			Plugin.Logger.LogInfo((object)text);
		}

		public override void Start()
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: 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_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Start();
			if (((NetworkBehaviour)this).IsOwner && !base.agent.isOnNavMesh)
			{
				Vector3 navMeshPosition = RoundManager.Instance.GetNavMeshPosition(((Component)this).transform.position, default(NavMeshHit), 15f, base.agentMask);
				if (RoundManager.Instance.GotNavMeshPositionResult)
				{
					((Behaviour)base.agent).enabled = false;
					((Component)this).transform.position = navMeshPosition;
					((Behaviour)base.agent).enabled = true;
				}
			}
			if (((Component)this).transform.position.y > -80f)
			{
				((EnemyAI)this).SetEnemyOutside(true);
			}
			base.enemyHP = 15;
			sounds = BorrowedSounds.Get();
			base.dieSFX = sounds.Death;
			base.creatureVoice.loop = true;
			AnimatorControllerParameter[] parameters = base.creatureAnimator.parameters;
			foreach (AnimatorControllerParameter val in parameters)
			{
				animatorParameters.Add(val.nameHash);
			}
			Transform transform = ((Component)base.creatureAnimator).transform;
			float y = transform.lossyScale.y;
			attackRange = 1.33f * y;
			float num = Mathf.Max(0f, 0.85f * (1.7f - 2.6f / y));
			biteHoldPoint = CreateChildPoint(transform, "BiteHoldPoint", new Vector3(0f, num, 0.67f), Quaternion.Euler(0f, 180f, 0f));
			bodyHoldPoint = CreateChildPoint(transform, "BodyHoldPoint", BodyHoldPosition, Quaternion.identity);
			previousPosition = ((Component)this).transform.position;
			EnemyAICollisionDetect componentInChildren = ((Component)this).GetComponentInChildren<EnemyAICollisionDetect>();
			BoxCollider val2 = default(BoxCollider);
			if ((Object)(object)componentInChildren != (Object)null && ((Component)componentInChildren).TryGetComponent<BoxCollider>(ref val2))
			{
				hitCollider = val2;
				standingColliderSize = val2.size;
				standingColliderCenter = val2.center;
			}
			base.currentBehaviourStateIndex = 0;
		}

		private Transform CreateChildPoint(Transform parent, string name, Vector3 localPosition, Quaternion localRotation)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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)
			Transform transform = new GameObject(name).transform;
			transform.SetParent(parent, false);
			transform.localPosition = localPosition;
			transform.localRotation = localRotation;
			return transform;
		}

		public override void Update()
		{
			//IL_0027: 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_0032: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Update();
			if (base.isEnemyDead)
			{
				return;
			}
			timeSinceContactDamage += Time.deltaTime;
			Vector3 val = ((Component)this).transform.position - previousPosition;
			float num = ((Vector3)(ref val)).magnitude / Mathf.Max(Time.deltaTime, 0.0001f);
			previousPosition = ((Component)this).transform.position;
			smoothedSpeed = Mathf.Lerp(smoothedSpeed, num, 10f * Time.deltaTime);
			SetAnimatorBool(MovingParameter, smoothedSpeed > 0.3f);
			SetAnimatorBool(ChasingParameter, base.currentBehaviourStateIndex != 0);
			UpdateVoice();
			PlayFootsteps();
			if (!((NetworkBehaviour)this).IsOwner)
			{
				return;
			}
			if (base.stunNormalizedTimer > 0f)
			{
				base.agent.speed = 0f;
				if (IsGrabbingPlayer)
				{
					CancelBiteClientRpc();
				}
			}
			else if ((Object)(object)base.targetPlayer != (Object)null && base.currentBehaviourStateIndex == 2)
			{
				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);
			}
		}

		private void UpdateVoice()
		{
			if (base.currentBehaviourStateIndex != voiceState)
			{
				bool flag = voiceState == 0 && base.currentBehaviourStateIndex == 1;
				voiceState = base.currentBehaviourStateIndex;
				AudioClip val = ((voiceState == 0) ? sounds.Breathing : sounds.Growl);
				if ((Object)(object)val != (Object)null && (Object)(object)base.creatureVoice.clip != (Object)(object)val)
				{
					base.creatureVoice.clip = val;
					base.creatureVoice.Play();
				}
				if (flag)
				{
					PlayOneShot(base.creatureVoice, sounds.Roar);
				}
			}
		}

		private void PlayFootsteps()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			AnimatorStateInfo currentAnimatorStateInfo = base.creatureAnimator.GetCurrentAnimatorStateInfo(0);
			float[] array = ((((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash == WalkState) ? WalkStepPhases : ((((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash == RunState) ? RunStepPhases : null));
			float normalizedTime = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime;
			if (array != null && ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash == footstepState && sounds.Footsteps.Length != 0)
			{
				float[] array2 = array;
				foreach (float num in array2)
				{
					if (Mathf.Floor(normalizedTime - num) > Mathf.Floor(footstepCycleTime - num))
					{
						PlayOneShot(base.creatureSFX, sounds.Footsteps[Random.Range(0, sounds.Footsteps.Length)], 0.6f);
					}
				}
			}
			footstepState = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash;
			footstepCycleTime = normalizedTime;
		}

		private static void PlayOneShot(AudioSource source, AudioClip? clip, float volume = 1f)
		{
			if ((Object)(object)clip != (Object)null)
			{
				source.PlayOneShot(clip, volume);
			}
		}

		private void LateUpdate()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)base.inSpecialAnimationWithPlayer != (Object)null)
			{
				((Component)base.inSpecialAnimationWithPlayer).transform.position = biteHoldPoint.position;
				((Component)base.inSpecialAnimationWithPlayer).transform.rotation = biteHoldPoint.rotation;
			}
		}

		public override void DoAIInterval()
		{
			//IL_006a: 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).DoAIInterval();
			if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead)
			{
				return;
			}
			switch (base.currentBehaviourStateIndex)
			{
			case 0:
				base.agent.speed = 2.2f;
				if (!roamSearch.inProgress && base.allAINodes != null && base.allAINodes.Length != 0)
				{
					((EnemyAI)this).StartSearch(((Component)this).transform.position, roamSearch);
				}
				if (FoundClosestPlayerInRange(30f, 4f))
				{
					((EnemyAI)this).StopSearch(roamSearch, true);
					lastSawTargetTime = Time.time;
					((EnemyAI)this).SwitchToBehaviourState(1);
				}
				break;
			case 1:
				base.agent.speed = (crawling ? 3f : 4.6f);
				if (!KeepOrFindTarget())
				{
					base.targetPlayer = null;
					base.movingTowardsTargetPlayer = false;
					((EnemyAI)this).SwitchToBehaviourState(0);
					break;
				}
				((EnemyAI)this).SetMovingTowardsTargetPlayer(base.targetPlayer);
				if (!crawling && Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) < attackRange && Time.time - lastAttackTime > 1.5f)
				{
					StartAttack();
				}
				break;
			case 2:
				base.agent.speed = 0f;
				break;
			}
		}

		private bool FoundClosestPlayerInRange(float range, float senseRange)
		{
			//IL_004f: 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)
			((EnemyAI)this).TargetClosestPlayer(1.5f, true, 70f, false, false, true);
			if ((Object)(object)base.targetPlayer == (Object)null)
			{
				((EnemyAI)this).TargetClosestPlayer(1.5f, false, 70f, false, false, true);
				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 KeepOrFindTarget()
		{
			PlayerControllerB targetPlayer = base.targetPlayer;
			if (((EnemyAI)this).TargetClosestPlayer(3f, true, 70f, false, false, true))
			{
				lastSawTargetTime = Time.time;
				return true;
			}
			if ((Object)(object)targetPlayer == (Object)null || !((EnemyAI)this).PlayerIsTargetable(targetPlayer, false, false, true))
			{
				return false;
			}
			base.targetPlayer = targetPlayer;
			return Time.time - lastSawTargetTime < 6f;
		}

		private void StartAttack()
		{
			lastAttackTime = Time.time;
			if (base.targetPlayer.health <= 60)
			{
				BeginBiteClientRpc((int)base.targetPlayer.playerClientId);
			}
			else
			{
				swipeCoroutine = ((MonoBehaviour)this).StartCoroutine(SwipeAttack());
			}
		}

		private IEnumerator SwipeAttack()
		{
			((EnemyAI)this).SwitchToBehaviourState(2);
			BeginSwipeClientRpc();
			yield return (object)new WaitForSeconds(0.7f);
			if (base.stunNormalizedTimer <= 0f)
			{
				SwipeHitClientRpc();
			}
			yield return (object)new WaitForSeconds(0.43f);
			if (base.stunNormalizedTimer <= 0f)
			{
				SwipeHitClientRpc();
			}
			yield return (object)new WaitForSeconds(0.47000003f);
			swipeCoroutine = null;
			lastAttackTime = Time.time;
			((EnemyAI)this).SwitchToBehaviourState(1);
		}

		private IEnumerator Bite(PlayerControllerB victim)
		{
			((EnemyAI)this).SwitchToBehaviourStateOnLocalClient(2);
			base.inSpecialAnimationWithPlayer = victim;
			victim.inSpecialInteractAnimation = true;
			victim.inAnimationWithEnemy = (EnemyAI)(object)this;
			if (!crawling)
			{
				base.creatureAnimator.ResetTrigger("cancelAttack");
				SetAnimatorTrigger("bite");
			}
			PlayOneShot(base.creatureSFX, sounds.Bite);
			yield return (object)new WaitForSeconds(2.7f);
			victim.KillPlayer(Vector3.zero, true, (CauseOfDeath)6, 0, default(Vector3), false);
			PlayOneShot(base.creatureSFX, sounds.Chew);
			((EnemyAI)this).CancelSpecialAnimationWithPlayer();
			float killTime = Time.time;
			yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)victim.deadBody != (Object)null || Time.time - killTime > 0.54999995f));
			if ((Object)(object)victim.deadBody != (Object)null)
			{
				heldBody = victim.deadBody;
				heldBody.attachedTo = bodyHoldPoint;
				heldBody.attachedLimb = heldBody.bodyParts[0];
				heldBody.matchPositionExactly = true;
			}
			yield return (object)new WaitForSeconds(Mathf.Max(0f, 0.54999995f - (Time.time - killTime)));
			DropBody();
			yield return (object)new WaitForSeconds(0.9200001f);
			biteCoroutine = null;
			lastAttackTime = Time.time;
			if (((NetworkBehaviour)this).IsOwner)
			{
				((EnemyAI)this).SwitchToBehaviourState(0);
			}
		}

		private void DropBody()
		{
			if (!((Object)(object)heldBody == (Object)null))
			{
				heldBody.attachedTo = null;
				heldBody.attachedLimb = null;
				heldBody.matchPositionExactly = false;
				heldBody = null;
			}
		}

		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)
			{
				return;
			}
			base.enemyHP -= force;
			if (force > 0 && base.enemyHP > 0 && sounds.Hurt.Length != 0)
			{
				PlayOneShot(base.creatureVoice, sounds.Hurt[Random.Range(0, sounds.Hurt.Length)]);
			}
			if (!((NetworkBehaviour)this).IsOwner)
			{
				return;
			}
			if (base.enemyHP <= 0)
			{
				((EnemyAI)this).KillEnemyOnOwnerClient(false);
				return;
			}
			bool flag = force > 1 || (force == 1 && hitID != -1);
			if (!crawling && base.enemyHP <= 3)
			{
				DropToFloor();
			}
			else if (IsGrabbingPlayer && flag)
			{
				CancelBiteClientRpc();
			}
		}

		private void DropToFloor()
		{
			if (IsGrabbingPlayer)
			{
				CancelBiteClientRpc();
			}
			if (swipeCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(swipeCoroutine);
				swipeCoroutine = null;
				lastAttackTime = Time.time;
				((EnemyAI)this).SwitchToBehaviourState(1);
			}
			SetCrawlingClientRpc(value: true);
		}

		public override void OnCollideWithPlayer(Collider other)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			if (crawling && !(timeSinceContactDamage < 1f))
			{
				PlayerControllerB val = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false);
				if (!((Object)(object)val == (Object)null) && !(((Component)this).transform.InverseTransformPoint(((Component)val).transform.position).z < 0f))
				{
					timeSinceContactDamage = 0f;
					PlayOneShot(base.creatureSFX, sounds.Bite);
					val.DamagePlayer(20, true, true, (CauseOfDeath)6, 0, false, default(Vector3));
				}
			}
		}

		public override void KillEnemy(bool destroy = false)
		{
			base.creatureVoice.Stop();
			if (swipeCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(swipeCoroutine);
				swipeCoroutine = null;
			}
			if (biteCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(biteCoroutine);
				biteCoroutine = null;
			}
			DropBody();
			((EnemyAI)this).KillEnemy(destroy);
		}

		private void SetAnimatorTrigger(string animationName)
		{
			if (animatorParameters.Contains(Animator.StringToHash(animationName)))
			{
				base.creatureAnimator.SetTrigger(animationName);
			}
		}

		private void SetAnimatorBool(int parameter, bool value)
		{
			if (animatorParameters.Contains(parameter))
			{
				base.creatureAnimator.SetBool(parameter, value);
			}
		}

		[ClientRpc]
		public void BeginSwipeClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
				{
					ClientRpcParams val2 = default(ClientRpcParams);
					FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(1252476453u, val2, (RpcDelivery)0);
					((NetworkBehaviour)this).__endSendClientRpc(ref val, 1252476453u, val2, (RpcDelivery)0);
				}
				if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
				{
					((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
					SetAnimatorTrigger("swingAttack");
					PlayOneShot(base.creatureSFX, sounds.Lunge);
				}
			}
		}

		[ClientRpc]
		public void SwipeHitClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: 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_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(1851400475u, val2, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 1851400475u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			Collider[] array = Physics.OverlapBox(attackArea.position, attackArea.localScale, attackArea.rotation, StartOfRound.Instance.playersMask);
			if (array.Length == 0)
			{
				return;
			}
			Collider[] array2 = array;
			foreach (Collider val3 in array2)
			{
				PlayerControllerB val4 = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(val3, false, false);
				if ((Object)(object)val4 != (Object)null)
				{
					val4.DamagePlayer(40, true, true, (CauseOfDeath)6, 0, false, default(Vector3));
					break;
				}
			}
		}

		[ClientRpc]
		public void BeginBiteClientRpc(int playerId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(233018450u, val2, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val, playerId);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 233018450u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				if (biteCoroutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(biteCoroutine);
				}
				biteCoroutine = ((MonoBehaviour)this).StartCoroutine(Bite(StartOfRound.Instance.allPlayerScripts[playerId]));
			}
		}

		[ClientRpc]
		public void CancelBiteClientRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(570585631u, val2, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 570585631u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			if (biteCoroutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(biteCoroutine);
				biteCoroutine = null;
				((EnemyAI)this).CancelSpecialAnimationWithPlayer();
				DropBody();
				if (!crawling)
				{
					SetAnimatorTrigger("cancelAttack");
				}
				lastAttackTime = Time.time;
				if (((NetworkBehaviour)this).IsOwner && !base.isEnemyDead)
				{
					((EnemyAI)this).SwitchToBehaviourState(1);
				}
			}
		}

		[ClientRpc]
		public void SetCrawlingClientRpc(bool value)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val2 = default(ClientRpcParams);
				FastBufferWriter val = ((NetworkBehaviour)this).__beginSendClientRpc(3676546287u, val2, (RpcDelivery)0);
				((FastBufferWriter)(ref val)).WriteValueSafe<bool>(ref value, default(ForPrimitives));
				((NetworkBehaviour)this).__endSendClientRpc(ref val, 3676546287u, val2, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost))
			{
				((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
				crawling = value;
				SetAnimatorBool(CrawlingParameter, value);
				if ((Object)(object)hitCollider != (Object)null)
				{
					float y = standingColliderSize.y;
					hitCollider.size = (Vector3)(value ? new Vector3(standingColliderSize.x, y * 0.37f, y * 1.1f) : standingColliderSize);
					hitCollider.center = (Vector3)(value ? new Vector3(0f, y * 0.37f * 0.5f, 0f) : standingColliderCenter);
				}
			}
		}

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

		protected override void __initializeRpcs()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Expected O, but got Unknown
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Expected O, but got Unknown
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Expected O, but got Unknown
			((NetworkBehaviour)this).__registerRpc(1252476453u, new RpcReceiveHandler(__rpc_handler_1252476453), "BeginSwipeClientRpc");
			((NetworkBehaviour)this).__registerRpc(1851400475u, new RpcReceiveHandler(__rpc_handler_1851400475), "SwipeHitClientRpc");
			((NetworkBehaviour)this).__registerRpc(233018450u, new RpcReceiveHandler(__rpc_handler_233018450), "BeginBiteClientRpc");
			((NetworkBehaviour)this).__registerRpc(570585631u, new RpcReceiveHandler(__rpc_handler_570585631), "CancelBiteClientRpc");
			((NetworkBehaviour)this).__registerRpc(3676546287u, new RpcReceiveHandler(__rpc_handler_3676546287), "SetCrawlingClientRpc");
			((EnemyAI)this).__initializeRpcs();
		}

		private static void __rpc_handler_1252476453(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((CaptainClarkAI)(object)target).BeginSwipeClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_1851400475(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((CaptainClarkAI)(object)target).SwipeHitClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_233018450(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				int playerId = default(int);
				ByteUnpacker.ReadValueBitPacked(reader, ref playerId);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((CaptainClarkAI)(object)target).BeginBiteClientRpc(playerId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_570585631(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((CaptainClarkAI)(object)target).CancelBiteClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_3676546287(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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool crawlingClientRpc = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref crawlingClientRpc, default(ForPrimitives));
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((CaptainClarkAI)(object)target).SetCrawlingClientRpc(crawlingClientRpc);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

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

		public static AssetBundle? ModAssets;

		internal static PluginConfig BoundConfig { get; private set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			BoundConfig = new PluginConfig(((BaseUnityPlugin)this).Config);
			InitializeNetworkBehaviours();
			string path = "modassets";
			ModAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), path));
			if ((Object)(object)ModAssets == (Object)null)
			{
				Logger.LogError((object)"Failed to load custom assets.");
				return;
			}
			EnemyType val = ModAssets.LoadAsset<EnemyType>("CaptainClark");
			TerminalNode val2 = ModAssets.LoadAsset<TerminalNode>("CaptainClarkTN");
			TerminalKeyword val3 = ModAssets.LoadAsset<TerminalKeyword>("CaptainClarkTK");
			val.PowerLevel = 3f;
			val.MaxCount = 1;
			val.increasedChanceInterior = -1;
			NetworkPrefabs.RegisterNetworkPrefab(val.enemyPrefab);
			BoundConfig.GetSpawnWeights(out Dictionary<LevelTypes, int> levelWeights, out Dictionary<string, int> customLevelWeights);
			Enemies.RegisterEnemy(val, levelWeights, customLevelWeights, val2, val3);
			Logger.LogInfo((object)"Plugin CaptainClark 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 = "CaptainClark";

		public const string PLUGIN_NAME = "CaptainClark";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace CaptainClark.Configuration
{
	public class PluginConfig
	{
		private const string DefaultSpawnWeights = "Experimentation:16,Assurance:24,Vow:9,Offense:54,March:66,Adamance:27,Rend:30,Dine:3,Titan:54,Artifice:92,Embrion:30,All:30";

		public ConfigEntry<string> SpawnWeights;

		public PluginConfig(ConfigFile cfg)
		{
			SpawnWeights = cfg.Bind<string>("General", "Spawn weights", "Experimentation:16,Assurance:24,Vow:9,Offense:54,March:66,Adamance:27,Rend:30,Dine:3,Titan:54,Artifice:92,Embrion:30,All:30", "How likely Captain Clark is to be the one picked when a moon spawns an indoor enemy, relative to that moon's other enemies.\nA list of Moon:weight pairs separated by commas. Higher is more common and 0 keeps him off that moon.\nAll is the weight on every moon that is not listed, modded moons included. A modded moon can be listed by its full name.\nThe default weights are the ones the game gives the Thumper.");
			ClearUnusedEntries(cfg);
		}

		public void GetSpawnWeights(out Dictionary<LevelTypes, int> levelWeights, out Dictionary<string, int> customLevelWeights)
		{
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			levelWeights = new Dictionary<LevelTypes, int>();
			customLevelWeights = new Dictionary<string, int>();
			string[] array = SpawnWeights.Value.Split(',', StringSplitOptions.RemoveEmptyEntries);
			foreach (string text in array)
			{
				string[] array2 = text.Split(':');
				if (array2.Length != 2 || !int.TryParse(array2[1].Trim(), out var result))
				{
					Plugin.Logger.LogWarning((object)("Ignoring the spawn weight \"" + text.Trim() + "\": it should look like Moon:weight."));
					continue;
				}
				string text2 = array2[0].Trim();
				if (Enum.TryParse<LevelTypes>(text2 + "Level", ignoreCase: true, out LevelTypes result2) || Enum.TryParse<LevelTypes>(text2, ignoreCase: true, out result2))
				{
					levelWeights[result2] = result;
				}
				else
				{
					customLevelWeights[text2] = result;
				}
			}
		}

		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 __GEN
{
	internal class NetworkVariableSerializationHelper
	{
		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeSerialization()
		{
		}
	}
}
namespace CaptainClark.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}