Decompiled source of RollerEnemy v1.0.6

Roller.dll

Decompiled a month ago
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using Roller;
using RollerEnemy;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("Roller")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Roller")]
[assembly: AssemblyTitle("Roller")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
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;
		}
	}
}
namespace RollerEnemy
{
	internal class RollerAI : EnemyAI
	{
		public enum RollerState
		{
			CLOSED,
			SEARCHING,
			ARMING,
			ROLLING
		}

		private const float speed = 10f;

		private const float pupilSpeed = 0.08f;

		private Animator animator;

		private Material material;

		private bool agressive = false;

		private bool hitWall = false;

		private float startSeeingPlayer = 0f;

		private RollerState rollerState = RollerState.CLOSED;

		private float timeSinceHittingPlayer = 0f;

		private float stateTimeLeft = 0f;

		private Vector3 direction = Vector3.zero;

		private Transform targetedPlayer = null;

		public Transform secondEye = null;

		private bool usingFirstEye = false;

		private AudioSource Scream;

		private AudioSource Arm;

		private AudioSource Roll;

		private AudioSource WallHit;

		private AudioSource Open;

		private AudioSource Close;

		private GameObject radarCircle;

		public override void Start()
		{
			base.AIIntervalTime = 0.2f;
			base.updatePositionThreshold = 0.4f;
			base.moveTowardsDestination = false;
			base.syncMovementSpeed = 0.22f;
			base.exitVentAnimationTime = 1.45f;
			base.enemyHP = 1;
			((EnemyAI)this).Start();
			animator = ((Component)this).GetComponent<Animator>();
			material = ((Renderer)((Component)((Component)this).transform.Find("EyeModel")).GetComponent<SkinnedMeshRenderer>()).materials[0];
			material.SetFloat("_EyeOpeness", 1f);
			Scream = ((Component)((Component)this).transform.Find("AudioSources").Find("Scream")).GetComponent<AudioSource>();
			Arm = ((Component)((Component)this).transform.Find("AudioSources").Find("Arm")).GetComponent<AudioSource>();
			Roll = ((Component)((Component)this).transform.Find("AudioSources").Find("Roll")).GetComponent<AudioSource>();
			WallHit = ((Component)((Component)this).transform.Find("AudioSources").Find("WallHit")).GetComponent<AudioSource>();
			Open = ((Component)((Component)this).transform.Find("AudioSources").Find("Open")).GetComponent<AudioSource>();
			Close = ((Component)((Component)this).transform.Find("AudioSources").Find("Close")).GetComponent<AudioSource>();
			radarCircle = ((Component)((Component)this).transform.Find("Circle")).gameObject;
		}

		public override void Update()
		{
			((EnemyAI)this).Update();
			if (!base.isEnemyDead)
			{
				if (radarCircle.layer != 14)
				{
					radarCircle.layer = 14;
				}
				timeSinceHittingPlayer -= Time.deltaTime;
				stateTimeLeft -= Time.deltaTime;
				CheckState();
			}
		}

		private void LateUpdate()
		{
			if ((Object)(object)targetedPlayer != (Object)null)
			{
				FocusEyeOnPlayer(targetedPlayer);
			}
		}

		private void CheckState()
		{
			//IL_0196: 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_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0266: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_027a: Unknown result type (might be due to invalid IL or missing references)
			switch (rollerState)
			{
			case RollerState.CLOSED:
				if (stateTimeLeft <= 0f)
				{
					SetStateServerRPC(RollerState.SEARCHING);
				}
				break;
			case RollerState.SEARCHING:
				if (stateTimeLeft <= 0f)
				{
					SetStateServerRPC(RollerState.CLOSED);
					Close.Play();
					agressive = false;
				}
				else if ((Object)(object)targetedPlayer == (Object)null)
				{
					material.SetFloat("_EyeOpeness", Mathf.Lerp(material.GetFloat("_EyeOpeness"), 1f, 0.08f));
					PlayerControllerB val = PlayerVisible();
					if ((Object)(object)val != (Object)null)
					{
						targetedPlayer = ((Component)val).transform;
						startSeeingPlayer = Time.time;
						if (val.actualClientId == GameNetworkManager.Instance.localPlayerController.actualClientId)
						{
							val.JumpToFearLevel(1f, true);
						}
						Scream.Play();
					}
				}
				else if (Time.time > startSeeingPlayer + 0.5f)
				{
					SetStateClientRPC(RollerState.ARMING);
				}
				break;
			case RollerState.ARMING:
				if (stateTimeLeft <= 0f)
				{
					SetStateClientRPC(RollerState.ROLLING);
					agressive = true;
					break;
				}
				direction = ((Component)targetedPlayer).transform.position - ((Component)this).transform.position;
				direction.y = 0f;
				((Vector3)(ref direction)).Normalize();
				agressive = true;
				((Component)this).transform.LookAt(new Vector3(((Component)targetedPlayer).transform.position.x, ((Component)this).transform.position.y, ((Component)targetedPlayer).transform.position.z));
				break;
			case RollerState.ROLLING:
				if (stateTimeLeft <= 0f && hitWall)
				{
					WallHit.Play();
					Roll.Stop();
					SetStateClientRPC(RollerState.CLOSED);
				}
				base.agent.Move(direction * 10f * Time.deltaTime);
				break;
			}
		}

		[ServerRpc]
		private void SetStateServerRPC(RollerState state)
		{
			SetStateClientRPC(state);
		}

		[ClientRpc]
		private void SetStateClientRPC(RollerState state)
		{
			rollerState = state;
			switch (state)
			{
			case RollerState.CLOSED:
				stateTimeLeft = 3f;
				targetedPlayer = null;
				hitWall = false;
				animator.SetBool("Closed", true);
				animator.SetBool("Rolling", false);
				animator.SetBool("Searching", false);
				break;
			case RollerState.SEARCHING:
				stateTimeLeft = 4f;
				animator.SetBool("Closed", false);
				animator.SetBool("Rolling", false);
				animator.SetBool("Searching", true);
				Open.Play();
				break;
			case RollerState.ARMING:
				animator.SetBool("Closed", false);
				animator.SetBool("Rolling", true);
				animator.SetBool("Searching", false);
				stateTimeLeft = 0.25f;
				Arm.Play();
				break;
			case RollerState.ROLLING:
				stateTimeLeft = 1f;
				animator.SetBool("Closed", false);
				animator.SetBool("Rolling", true);
				animator.SetBool("Searching", false);
				Roll.Play(0.25);
				break;
			}
		}

		private PlayerControllerB PlayerVisible()
		{
			PlayerControllerB[] allPlayersInLineOfSight = ((EnemyAI)this).GetAllPlayersInLineOfSight(30f, 70, base.eye, 3f, -1);
			if (allPlayersInLineOfSight != null && allPlayersInLineOfSight.Length != 0)
			{
				usingFirstEye = true;
				return allPlayersInLineOfSight[0];
			}
			allPlayersInLineOfSight = ((EnemyAI)this).GetAllPlayersInLineOfSight(30f, 70, secondEye, 3f, -1);
			if (allPlayersInLineOfSight != null && allPlayersInLineOfSight.Length != 0)
			{
				usingFirstEye = false;
				return allPlayersInLineOfSight[0];
			}
			return null;
		}

		private void FocusEyeOnPlayer(Transform player)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			base.eye.LookAt(player.position + new Vector3(0f, 1f, 0f));
			if (!usingFirstEye)
			{
			}
			material.SetFloat("_EyeOpeness", Mathf.Lerp(material.GetFloat("_EyeOpeness"), -0.6f, 0.08f));
		}

		public override void OnCollideWithPlayer(Collider other)
		{
			//IL_0051: 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)
			((EnemyAI)this).OnCollideWithPlayer(other);
			if (!agressive || timeSinceHittingPlayer >= 0f)
			{
				return;
			}
			PlayerControllerB val = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false);
			if ((Object)(object)val != (Object)null)
			{
				timeSinceHittingPlayer = 0.5f;
				val.DamagePlayer(90, true, true, (CauseOfDeath)6, 2, false, default(Vector3));
				if (val.actualClientId == GameNetworkManager.Instance.localPlayerController.actualClientId)
				{
					val.JumpToFearLevel(1f, true);
				}
			}
		}

		public void WallSignal()
		{
			if (rollerState == RollerState.ROLLING && stateTimeLeft <= 0f)
			{
				hitWall = true;
			}
		}
	}
	[BepInPlugin("RollerEnemy", "RollerEnemy", "1.0.0")]
	public class RollerEnemyPlugin : BaseUnityPlugin
	{
		public static EnemyType EnemyType;

		internal static ManualLogSource Log;

		private const string EnemyTypePath = "Assets/Roller/RollerType.asset";

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin RollerEnemy START!");
			LoadAssets();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin RollerEnemy LOADED!");
		}

		private void LoadAssets()
		{
			//IL_00da: 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_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			Assets.PopulateAssets();
			LoadNetWeaver();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin RollerEnemy ASSETS POPULATED!");
			Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), (string)null);
			if (Assets.MainAssetBundle.Contains("Assets/Roller/RollerType.asset"))
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin RollerEnemy VALID PATH!");
				EnemyType = Assets.MainAssetBundle.LoadAsset<EnemyType>("Assets/Roller/RollerType.asset");
				if ((Object)(object)EnemyType == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin RollerEnemy ENEMYTYPE IS NULL!");
					return;
				}
				if ((Object)(object)EnemyType.enemyPrefab == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin RollerEnemy ROLLER ENEMY PREFAB MISSING!");
					return;
				}
				AddScripts(EnemyType);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Registering Roller as Enemy");
				LevelTypes val = (LevelTypes)(-1);
				SpawnType val2 = (SpawnType)0;
				TerminalNode val3 = ScriptableObject.CreateInstance<TerminalNode>();
				val3.displayText = "Roller \n\nDanger level: 65%\n\nSpiky roller which rolls whenever it sees danger.They are shy, but very dangerous creatures. They close themselves in their shells, but check regurarly for any dangers. Beware of their scream, as it might mean a certain death!\n\n";
				val3.clearPreviousText = true;
				val3.maxCharactersToType = 2000;
				val3.creatureName = "Roller";
				val3.creatureFileID = 28888;
				TerminalKeyword val4 = TerminalUtils.CreateTerminalKeyword("roller", false, (CompatibleNoun[])null, val3, (TerminalKeyword)null, false);
				NetworkPrefabs.RegisterNetworkPrefab(EnemyType.enemyPrefab);
				Enemies.RegisterEnemy(EnemyType, 25, val, val2, val3, val4);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin RollerEnemy ROLLER ENEMY TYPE LOADED CORRECTLY!");
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin RollerEnemy INVALID PATH!");
			}
		}

		private void AddScripts(EnemyType rollerType)
		{
			GameObject enemyPrefab = rollerType.enemyPrefab;
			enemyPrefab.AddComponent<RollerAI>();
			((EnemyAI)enemyPrefab.GetComponent<RollerAI>()).enemyType = rollerType;
			((EnemyAI)enemyPrefab.GetComponent<RollerAI>()).eye = enemyPrefab.transform.Find("Roller Armature").Find("Eye");
			enemyPrefab.GetComponent<RollerAI>().secondEye = enemyPrefab.transform.Find("Roller Armature").Find("Eye").Find("EyeOther");
			((Component)enemyPrefab.transform.Find("WallSensor")).gameObject.AddComponent<WallSensor>();
			((Component)enemyPrefab.transform.Find("WallSensor")).gameObject.GetComponent<WallSensor>().roller = enemyPrefab.GetComponent<RollerAI>();
			enemyPrefab.GetComponent<EnemyAICollisionDetect>().mainScript = (EnemyAI)(object)enemyPrefab.GetComponent<RollerAI>();
		}

		private void LoadNetWeaver()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				try
				{
					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);
						}
					}
				}
				catch
				{
				}
			}
		}
	}
	public static class Assets
	{
		public static string mainAssetBundleName = "rollerbundle";

		public static AssetBundle MainAssetBundle = null;

		private static string GetAssemblyName()
		{
			return Assembly.GetExecutingAssembly().GetName().Name;
		}

		public static void PopulateAssets()
		{
			if ((Object)(object)MainAssetBundle == (Object)null)
			{
				Console.WriteLine(GetAssemblyName() + "." + mainAssetBundleName);
				using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetAssemblyName() + "." + mainAssetBundleName);
				MainAssetBundle = AssetBundle.LoadFromStream(stream);
			}
		}
	}
}
namespace Roller
{
	[HarmonyPatch]
	internal class EnemyPatches
	{
		[HarmonyPatch(typeof(StartOfRound), "Awake")]
		[HarmonyPostfix]
		private static void RegisterEnemy(StartOfRound __instance)
		{
			SelectableLevel[] levels = __instance.levels;
			HandleSpawnInAny(levels);
		}

		private static void HandleSpawnInAny(SelectableLevel[] levels)
		{
		}
	}
	internal class WallSensor : MonoBehaviour
	{
		public RollerAI roller;

		private void OnTriggerStay(Collider other)
		{
			if (((Component)other).gameObject.layer == LayerMask.NameToLayer("Room") || ((Component)other).gameObject.layer == LayerMask.NameToLayer("Colliders"))
			{
				roller.WallSignal();
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}