Decompiled source of Rayllan v1.1.0

RayllanMonster.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.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("RayllanMonster")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("RayllanMonster")]
[assembly: AssemblyTitle("RayllanMonster")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[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 RayllanMonster
{
	[BepInPlugin("marlko.rayllanmonster", "Rayllan", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string GUID = "marlko.rayllanmonster";

		public const string NAME = "Rayllan";

		public const string VERSION = "1.1.0";

		private ConfigEntry<int> spawnWeight;

		private void Awake()
		{
			spawnWeight = ((BaseUnityPlugin)this).Config.Bind<int>("Spawning", "SpawnWeight", 40, "How often Rayllan spawns inside the facility. Higher = more common (vanilla enemies are roughly 1-100).");
			AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "rayllan"));
			if ((Object)(object)val == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)"Couldn't load the 'rayllan' asset bundle. Is it next to RayllanMonster.dll?");
				return;
			}
			EnemyType val2 = val.LoadAsset<EnemyType>("Assets/Rayllan/RayllanEnemy.asset");
			TerminalNode val3 = val.LoadAsset<TerminalNode>("Assets/Rayllan/RayllanTN.asset");
			TerminalKeyword val4 = val.LoadAsset<TerminalKeyword>("Assets/Rayllan/RayllanTK.asset");
			NetworkPrefabs.RegisterNetworkPrefab(val2.enemyPrefab);
			Enemies.RegisterEnemy(val2, spawnWeight.Value, (LevelTypes)(-1), (SpawnType)0, val3, val4);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Rayllan is loose in the facility.");
		}
	}
	public class RayllanAI : EnemyAI
	{
		public float roamSpeed = 3.5f;

		public float chaseSpeed = 9f;

		public float chaseStartSpeed = 3f;

		public float chaseRampSeconds = 6f;

		public int sightRange = 30;

		public float giveUpAfterSeconds = 5f;

		public int hitDamage = 35;

		public float hitCooldown = 1.2f;

		public AudioClip[] spottedClips;

		public AudioClip[] attackClips;

		public AudioClip[] idleClips;

		private float timeSinceSawTarget;

		private float timeSinceHit;

		private float idleSoundTimer;

		private float chaseTime;

		private float stuckTime;

		private int lastState = -1;

		private AISearchRoutine roamSearch = new AISearchRoutine();

		private Transform body;

		private Vector3 bodyRestPos;

		private Vector3 lastPos;

		private float waddlePhase;

		private float smoothedSpeed;

		public override void Start()
		{
			//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_0046: 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)
			((EnemyAI)this).Start();
			idleSoundTimer = Random.Range(8f, 15f);
			body = ((Component)this).transform.Find("RayllanBody");
			if ((Object)(object)body != (Object)null)
			{
				bodyRestPos = body.localPosition;
			}
			lastPos = ((Component)this).transform.position;
			if (((NetworkBehaviour)this).IsOwner)
			{
				EnterRoaming();
			}
		}

		public override void Update()
		{
			((EnemyAI)this).Update();
			if (base.isEnemyDead)
			{
				return;
			}
			timeSinceHit += Time.deltaTime;
			timeSinceSawTarget += Time.deltaTime;
			if ((Object)(object)base.creatureAnimator != (Object)null)
			{
				base.creatureAnimator.SetBool("Chasing", base.currentBehaviourStateIndex == 1);
			}
			if (base.currentBehaviourStateIndex != lastState)
			{
				if (base.currentBehaviourStateIndex == 1 && lastState != -1)
				{
					chaseTime = 0f;
					PlayRandom(spottedClips, 1f);
					if ((Object)(object)base.creatureAnimator != (Object)null)
					{
						base.creatureAnimator.SetTrigger("Spotted");
					}
				}
				lastState = base.currentBehaviourStateIndex;
			}
			if (((NetworkBehaviour)this).IsOwner && base.currentBehaviourStateIndex == 1)
			{
				chaseTime += Time.deltaTime;
				float num = Mathf.Clamp01(chaseTime / Mathf.Max(0.01f, chaseRampSeconds));
				base.agent.speed = Mathf.Lerp(chaseStartSpeed, chaseSpeed, num * num);
			}
			if (base.currentBehaviourStateIndex == 0)
			{
				idleSoundTimer -= Time.deltaTime;
				if (idleSoundTimer <= 0f)
				{
					PlayRandom(idleClips, 0.8f);
					idleSoundTimer = Random.Range(10f, 20f);
				}
			}
			Waddle();
		}

		private void Waddle()
		{
			//IL_0021: 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_003f: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: 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)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)body == (Object)null) && !(Time.deltaTime <= 0f))
			{
				float num = Vector3.Distance(((Component)this).transform.position, lastPos) / Time.deltaTime;
				lastPos = ((Component)this).transform.position;
				smoothedSpeed = Mathf.Lerp(smoothedSpeed, num, Time.deltaTime * 6f);
				float num2 = Mathf.Clamp01(smoothedSpeed / 1.5f);
				waddlePhase += Time.deltaTime * (2f + smoothedSpeed * 1.6f);
				float num3 = Mathf.Abs(Mathf.Sin(waddlePhase)) * 0.06f * num2 * (0.6f + smoothedSpeed / 9f);
				float num4 = Mathf.Sin(waddlePhase) * 9f * num2;
				float num5 = Mathf.Clamp(smoothedSpeed * 1.8f, 0f, 16f);
				body.localPosition = bodyRestPos + new Vector3(0f, num3, 0f);
				body.localRotation = Quaternion.Euler(num5, 0f, num4);
			}
		}

		public override void DoAIInterval()
		{
			//IL_0021: 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_00e0: 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_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).DoAIInterval();
			if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead)
			{
				return;
			}
			Vector3 velocity = base.agent.velocity;
			if (((Vector3)(ref velocity)).sqrMagnitude < 0.04f)
			{
				stuckTime += base.AIIntervalTime;
			}
			else
			{
				stuckTime = 0f;
			}
			switch (base.currentBehaviourStateIndex)
			{
			case 0:
			{
				PlayerControllerB val = ((EnemyAI)this).CheckLineOfSightForPlayer(60f, sightRange, 2);
				if ((Object)(object)val != (Object)null && !val.isPlayerDead)
				{
					StartChasing(val);
				}
				else if (!roamSearch.inProgress || stuckTime > 2.5f)
				{
					stuckTime = 0f;
					((EnemyAI)this).StopSearch(roamSearch, true);
					base.agent.speed = roamSpeed;
					((EnemyAI)this).StartSearch(((Component)this).transform.position, roamSearch);
				}
				break;
			}
			case 1:
				if ((Object)(object)base.targetPlayer == (Object)null || base.targetPlayer.isPlayerDead || !base.targetPlayer.isInsideFactory)
				{
					EnterRoaming();
					break;
				}
				if (((EnemyAI)this).CheckLineOfSightForPosition(((Component)base.targetPlayer.gameplayCamera).transform.position, 120f, sightRange, -1f, (Transform)null))
				{
					timeSinceSawTarget = 0f;
				}
				if (timeSinceSawTarget > giveUpAfterSeconds)
				{
					EnterRoaming();
				}
				else if (stuckTime > 2.5f && Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) > 2f)
				{
					EnterRoaming();
				}
				else
				{
					((EnemyAI)this).SetMovingTowardsTargetPlayer(base.targetPlayer);
				}
				break;
			}
		}

		private void StartChasing(PlayerControllerB player)
		{
			((EnemyAI)this).StopSearch(roamSearch, true);
			base.targetPlayer = player;
			timeSinceSawTarget = 0f;
			chaseTime = 0f;
			stuckTime = 0f;
			base.agent.speed = chaseStartSpeed;
			((EnemyAI)this).SwitchToBehaviourClientRpc(1);
		}

		private void EnterRoaming()
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			base.targetPlayer = null;
			base.movingTowardsTargetPlayer = false;
			chaseTime = 0f;
			stuckTime = 0f;
			((EnemyAI)this).StopSearch(roamSearch, true);
			base.agent.speed = roamSpeed;
			if (base.currentBehaviourStateIndex != 0)
			{
				((EnemyAI)this).SwitchToBehaviourClientRpc(0);
			}
			((EnemyAI)this).StartSearch(((Component)this).transform.position, roamSearch);
		}

		public override void OnCollideWithPlayer(Collider other)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).OnCollideWithPlayer(other);
			if (timeSinceHit < hitCooldown)
			{
				return;
			}
			PlayerControllerB val = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false);
			if (!((Object)(object)val == (Object)null))
			{
				timeSinceHit = 0f;
				val.DamagePlayer(hitDamage, true, true, (CauseOfDeath)6, 0, false, default(Vector3));
				PlayRandom(attackClips, 1f);
				if ((Object)(object)base.creatureAnimator != (Object)null)
				{
					base.creatureAnimator.SetTrigger("Attack");
				}
			}
		}

		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 (base.enemyHP <= 0)
			{
				if (((NetworkBehaviour)this).IsOwner)
				{
					((EnemyAI)this).KillEnemyOnOwnerClient(false);
				}
			}
			else if (((NetworkBehaviour)this).IsOwner && (Object)(object)playerWhoHit != (Object)null && base.currentBehaviourStateIndex != 1)
			{
				StartChasing(playerWhoHit);
			}
		}

		private void PlayRandom(AudioClip[] clips, float volume)
		{
			if (clips != null && clips.Length != 0 && !((Object)(object)base.creatureVoice == (Object)null))
			{
				AudioClip val = clips[Random.Range(0, clips.Length)];
				base.creatureVoice.PlayOneShot(val, volume);
				WalkieTalkie.TransmitOneShotAudio(base.creatureVoice, val, volume);
			}
		}
	}
}