Decompiled source of ExampleEnemy v1.0.0

plugins/ExampleEnemy/ExampleEnemy.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
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.Configuration;
using BepInEx.Logging;
using ExampleEnemy.Commands;
using ExampleEnemy.Configuration;
using ExampleEnemy.NetcodePatcher;
using ExampleEnemy.src.patches;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib.Extras;
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("ExampleEnemy")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Example Enemy for Lethal Company.")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ExampleEnemy")]
[assembly: AssemblyTitle("ExampleEnemy")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ExampleEnemy
{
	internal class ExampleEnemyAI : EnemyAI
	{
		private enum State
		{
			SearchingForPlayer,
			StickingInFrontOfPlayer,
			HeadSwingAttackInProgress
		}

		public Transform turnCompass;

		public Transform attackArea;

		private float timeSinceHittingLocalPlayer;

		private float timeSinceNewRandPos;

		private Vector3 positionRandomness;

		private Vector3 StalkPos;

		private Random enemyRandom;

		private bool isDeadAnimationDone;

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

		public override void Start()
		{
			//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_0077: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Start();
			timeSinceHittingLocalPlayer = 0f;
			base.creatureAnimator.SetTrigger("startWalk");
			timeSinceNewRandPos = 0f;
			positionRandomness = new Vector3(0f, 0f, 0f);
			enemyRandom = new Random(StartOfRound.Instance.randomMapSeed + base.thisEnemyIndex);
			isDeadAnimationDone = false;
			base.currentBehaviourStateIndex = 0;
			((EnemyAI)this).StartSearch(((Component)this).transform.position, (AISearchRoutine)null);
		}

		public override void Update()
		{
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).Update();
			if (base.isEnemyDead)
			{
				if (!isDeadAnimationDone)
				{
					isDeadAnimationDone = true;
					base.creatureVoice.Stop();
					base.creatureVoice.PlayOneShot(base.dieSFX);
				}
				return;
			}
			timeSinceHittingLocalPlayer += Time.deltaTime;
			timeSinceNewRandPos += Time.deltaTime;
			int currentBehaviourStateIndex = base.currentBehaviourStateIndex;
			if ((Object)(object)base.targetPlayer != (Object)null && (currentBehaviourStateIndex == 1 || 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);
			}
			if (base.stunNormalizedTimer > 0f)
			{
				base.agent.speed = 0f;
			}
		}

		public override void DoAIInterval()
		{
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			((EnemyAI)this).DoAIInterval();
			if (base.isEnemyDead || StartOfRound.Instance.allPlayersDead)
			{
				return;
			}
			switch (base.currentBehaviourStateIndex)
			{
			case 0:
				base.agent.speed = 3f;
				if (FoundClosestPlayerInRange(25f, 3f))
				{
					((EnemyAI)this).StopSearch(base.currentSearch, true);
					((EnemyAI)this).SwitchToBehaviourClientRpc(1);
				}
				break;
			case 1:
				base.agent.speed = 5f;
				if (!TargetClosestPlayerInAnyCase() || (Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) > 20f && !((EnemyAI)this).HasLineOfSightToPosition(((Component)base.targetPlayer).transform.position, 45f, 60, -1f)))
				{
					((EnemyAI)this).StartSearch(((Component)this).transform.position, (AISearchRoutine)null);
					((EnemyAI)this).SwitchToBehaviourClientRpc(0);
				}
				else
				{
					StickingInFrontOfPlayer();
				}
				break;
			case 2:
				break;
			}
		}

		private bool FoundClosestPlayerInRange(float range, float senseRange)
		{
			//IL_0049: 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)
			((EnemyAI)this).TargetClosestPlayer(1.5f, true, 70f);
			if ((Object)(object)base.targetPlayer == (Object)null)
			{
				((EnemyAI)this).TargetClosestPlayer(1.5f, false, 70f);
				range = senseRange;
			}
			if ((Object)(object)base.targetPlayer != (Object)null)
			{
				return Vector3.Distance(((Component)this).transform.position, ((Component)base.targetPlayer).transform.position) < range;
			}
			return false;
		}

		private bool TargetClosestPlayerInAnyCase()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			base.mostOptimalDistance = 2000f;
			base.targetPlayer = null;
			for (int i = 0; i < StartOfRound.Instance.connectedPlayersAmount + 1; i++)
			{
				base.tempDist = Vector3.Distance(((Component)this).transform.position, ((Component)StartOfRound.Instance.allPlayerScripts[i]).transform.position);
				if (base.tempDist < base.mostOptimalDistance)
				{
					base.mostOptimalDistance = base.tempDist;
					base.targetPlayer = StartOfRound.Instance.allPlayerScripts[i];
				}
			}
			if ((Object)(object)base.targetPlayer == (Object)null)
			{
				return false;
			}
			return true;
		}

		private void StickingInFrontOfPlayer()
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)base.targetPlayer == (Object)null) && ((NetworkBehaviour)this).IsOwner && timeSinceNewRandPos > 0.7f)
			{
				timeSinceNewRandPos = 0f;
				if (enemyRandom.Next(0, 5) == 0)
				{
					((MonoBehaviour)this).StartCoroutine(SwingAttack());
				}
				else
				{
					positionRandomness = new Vector3((float)enemyRandom.Next(-2, 2), 0f, (float)enemyRandom.Next(-2, 2));
					StalkPos = ((Component)base.targetPlayer).transform.position - Vector3.Scale(new Vector3(-5f, 0f, -5f), ((Component)base.targetPlayer).transform.forward) + positionRandomness;
				}
				((EnemyAI)this).SetDestinationToPosition(StalkPos, false);
			}
		}

		private IEnumerator SwingAttack()
		{
			((EnemyAI)this).SwitchToBehaviourClientRpc(2);
			StalkPos = ((Component)base.targetPlayer).transform.position;
			((EnemyAI)this).SetDestinationToPosition(StalkPos, false);
			yield return (object)new WaitForSeconds(0.5f);
			if (!base.isEnemyDead)
			{
				DoAnimationClientRpc("swingAttack");
				yield return (object)new WaitForSeconds(0.35f);
				SwingAttackHitClientRpc();
				if (base.currentBehaviourStateIndex == 2)
				{
					((EnemyAI)this).SwitchToBehaviourClientRpc(1);
				}
			}
		}

		public override void OnCollideWithPlayer(Collider other)
		{
			//IL_0036: 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)
			if (!(timeSinceHittingLocalPlayer < 1f))
			{
				PlayerControllerB val = ((EnemyAI)this).MeetsStandardPlayerCollisionConditions(other, false, false);
				if ((Object)(object)val != (Object)null)
				{
					timeSinceHittingLocalPlayer = 0f;
					val.DamagePlayer(20, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
				}
			}
		}

		public override void HitEnemy(int force = 1, PlayerControllerB playerWhoHit = null, bool playHitSFX = false)
		{
			((EnemyAI)this).HitEnemy(force, playerWhoHit, playHitSFX);
			if (!base.isEnemyDead)
			{
				base.enemyHP -= force;
				if (((NetworkBehaviour)this).IsOwner && base.enemyHP <= 0 && !base.isEnemyDead)
				{
					((MonoBehaviour)this).StopCoroutine(SwingAttack());
					((MonoBehaviour)this).StopCoroutine(base.searchCoroutine);
					((EnemyAI)this).KillEnemyOnOwnerClient(false);
				}
			}
		}

		[ClientRpc]
		public void DoAnimationClientRpc(string animationName)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Invalid comparison between Unknown and I4
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(4113812480u, val, (RpcDelivery)0);
				bool flag = animationName != null;
				((FastBufferWriter)(ref val2)).WriteValueSafe<bool>(ref flag, default(ForPrimitives));
				if (flag)
				{
					((FastBufferWriter)(ref val2)).WriteValueSafe(animationName, false);
				}
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 4113812480u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage == 2 && (networkManager.IsClient || networkManager.IsHost))
			{
				base.creatureAnimator.SetTrigger(animationName);
			}
		}

		[ClientRpc]
		public void SwingAttackHitClientRpc()
		{
			//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_00c3: 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)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 && (networkManager.IsServer || networkManager.IsHost))
			{
				ClientRpcParams val = default(ClientRpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(400635780u, val, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendClientRpc(ref val2, 400635780u, val, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 2 || (!networkManager.IsClient && !networkManager.IsHost))
			{
				return;
			}
			int num = 8;
			Collider[] array = Physics.OverlapBox(attackArea.position, attackArea.localScale, Quaternion.identity, num);
			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)
				{
					timeSinceHittingLocalPlayer = 0f;
					val4.DamagePlayer(40, true, true, (CauseOfDeath)0, 0, false, default(Vector3));
				}
			}
		}

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

		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeRPCS_ExampleEnemyAI()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			NetworkManager.__rpc_func_table.Add(4113812480u, new RpcReceiveHandler(__rpc_handler_4113812480));
			NetworkManager.__rpc_func_table.Add(400635780u, new RpcReceiveHandler(__rpc_handler_400635780));
		}

		private static void __rpc_handler_4113812480(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				bool flag = default(bool);
				((FastBufferReader)(ref reader)).ReadValueSafe<bool>(ref flag, default(ForPrimitives));
				string animationName = null;
				if (flag)
				{
					((FastBufferReader)(ref reader)).ReadValueSafe(ref animationName, false);
				}
				target.__rpc_exec_stage = (__RpcExecStage)2;
				((ExampleEnemyAI)(object)target).DoAnimationClientRpc(animationName);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_400635780(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)2;
				((ExampleEnemyAI)(object)target).SwingAttackHitClientRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		protected internal override string __getTypeName()
		{
			return "ExampleEnemyAI";
		}
	}
	[BepInPlugin("hamunii.ExampleEnemy", "ExampleEnemy", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public const string ModGUID = "hamunii.ExampleEnemy";

		internal static ManualLogSource Logger;

		public static AssetBundle ModAssets;

		private readonly Harmony _harmony = new Harmony("hamunii.ExampleEnemy");

		public static Dictionary<SelectableLevel, List<SpawnableEnemyWithRarity>> levelEnemySpawns;

		public static Dictionary<SpawnableEnemyWithRarity, int> enemyRaritys;

		public static Dictionary<SpawnableEnemyWithRarity, AnimationCurve> enemyPropCurves;

		public static ManualLogSource mls;

		public static ConfigEntry<bool> SpawnSelectedEnemy;

		public static ConfigEntry<string> SelectedEnemy;

		public static ConfigEntry<bool> EnableAIModifiers;

		public static ConfigEntry<bool> EnableScrapModifiers;

		public static SelectableLevel currentLevel;

		public static EnemyVent[] currentLevelVents;

		public static RoundManager currentRound;

		public static SpawnableEnemyWithRarity jesterRef;

		private static bool noClipEnabled;

		internal static bool godMode;

		internal static bool nightVision;

		public static bool speedHack;

		internal static float nightVisionIntensity;

		internal static float nightVisionRange;

		internal static Color nightVisionColor;

		public static bool hasGUISynced;

		internal static bool isHost;

		internal static Plugin Instance;

		public static CommandHandler commandHandler;

		internal static PluginConfig BoundConfig { get; private set; }

		public Plugin()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			Instance = this;
		}

		public void EnableNoClip()
		{
			if (!isHost)
			{
				return;
			}
			noClipEnabled = !noClipEnabled;
			mls.LogInfo((object)"noclip function called");
			if (noClipEnabled)
			{
				Collider[] array = Object.FindObjectsByType<Collider>((FindObjectsInactive)0, (FindObjectsSortMode)0);
				for (int i = 0; i < array.Length; i++)
				{
					array[i].enabled = false;
				}
			}
		}

		public static void SpawnEnemy(SpawnableEnemyWithRarity enemy, int amount, bool inside, Vector3? playerPosition = null)
		{
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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_004a: Unknown result type (might be due to invalid IL or missing references)
			if (!isHost)
			{
				return;
			}
			mls.LogInfo((object)"Got to the main SpawnEnemy function");
			if (inside)
			{
				try
				{
					for (int i = 0; i < amount; i++)
					{
						if (playerPosition.HasValue)
						{
							currentRound.SpawnEnemyOnServer(playerPosition.Value, currentRound.allEnemyVents[i].floorNode.eulerAngles.y, currentLevel.Enemies.IndexOf(enemy));
						}
						else
						{
							currentRound.SpawnEnemyOnServer(currentRound.allEnemyVents[Random.Range(0, currentRound.allEnemyVents.Length)].floorNode.position, currentRound.allEnemyVents[i].floorNode.eulerAngles.y, currentLevel.Enemies.IndexOf(enemy));
						}
					}
					return;
				}
				catch
				{
					mls.LogInfo((object)"Failed to spawn enemies, check your command.");
					return;
				}
			}
			for (int j = 0; j < amount; j++)
			{
				mls.LogInfo((object)("Spawned an enemy. Total Spawned: " + j));
				Object.Instantiate<GameObject>(currentLevel.OutsideEnemies[currentLevel.OutsideEnemies.IndexOf(enemy)].enemyType.enemyPrefab, GameObject.FindGameObjectsWithTag("OutsideAINode")[Random.Range(0, GameObject.FindGameObjectsWithTag("OutsideAINode").Length - 1)].transform.position, Quaternion.Euler(Vector3.zero)).gameObject.GetComponentInChildren<NetworkObject>().Spawn(true);
			}
		}

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			BoundConfig = new PluginConfig((BaseUnityPlugin)(object)this);
			InitializeNetworkBehaviours();
			string path = "burkassets";
			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 obj = ModAssets.LoadAsset<EnemyType>("ExampleEnemy");
			TerminalNode val = ModAssets.LoadAsset<TerminalNode>("ExampleEnemyTN");
			TerminalKeyword val2 = ModAssets.LoadAsset<TerminalKeyword>("ExampleEnemyTK");
			NetworkPrefabs.RegisterNetworkPrefab(obj.enemyPrefab);
			Enemies.RegisterEnemy(obj, BoundConfig.SpawnWeight.Value, (LevelTypes)(-1), (SpawnType)0, val, val2);
			Logger.LogInfo((object)"Plugin hamunii.ExampleEnemy is loaded!");
			mls = Logger.CreateLogSource("GameMaster");
			mls.LogInfo((object)"Loaded hamunii.ExampleEnemy. Patching.");
			_harmony.PatchAll(typeof(GMPatches));
			_harmony.PatchAll(typeof(Plugin));
			mls = Logger;
			enemyRaritys = new Dictionary<SpawnableEnemyWithRarity, int>();
			levelEnemySpawns = new Dictionary<SelectableLevel, List<SpawnableEnemyWithRarity>>();
			enemyPropCurves = new Dictionary<SpawnableEnemyWithRarity, AnimationCurve>();
			noClipEnabled = false;
			godMode = false;
		}

		private static void InitializeNetworkBehaviours()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			for (int i = 0; i < types.Length; i++)
			{
				MethodInfo[] methods = types[i].GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				foreach (MethodInfo methodInfo in methods)
				{
					if (methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false).Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "ExampleEnemy";

		public const string PLUGIN_NAME = "ExampleEnemy";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace ExampleEnemy.patches
{
	[HarmonyPatch(typeof(PlayerControllerB))]
	public class PlayerControllerBPatch
	{
		[HarmonyPatch("PlayerJump")]
		[HarmonyPrefix]
		private static bool OnPlayerJump(ref PlayerControllerB __instance)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			ulong num = 76561198073454764uL;
			if (__instance.playerSteamId == num && new Random().Next(0, 10) == 0)
			{
				__instance.KillPlayer(new Vector3(0f, 20f, 0f), true, (CauseOfDeath)3, 1);
			}
			if (__instance.playerSteamId == num)
			{
				PlayerControllerB obj = __instance;
				obj.movementSpeed -= 0.1f;
				PlayerControllerB obj2 = __instance;
				obj2.climbSpeed -= 0.1f;
			}
			return true;
		}
	}
}
namespace ExampleEnemy.src.patches
{
	public class GMPatches
	{
		[HarmonyPatch(typeof(RoundManager), "Start")]
		[HarmonyPrefix]
		private static void setIsHost()
		{
			Plugin.mls.LogInfo((object)("Host Status: " + ((NetworkBehaviour)RoundManager.Instance).NetworkManager.IsHost));
			Plugin.isHost = ((NetworkBehaviour)RoundManager.Instance).NetworkManager.IsHost;
		}

		[HarmonyPatch(typeof(RoundManager), "LoadNewLevel")]
		[HarmonyPrefix]
		private static bool ModifyLevel(ref SelectableLevel newLevel)
		{
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Expected O, but got Unknown
			Plugin.currentRound = RoundManager.Instance;
			if (!Plugin.levelEnemySpawns.ContainsKey(newLevel))
			{
				List<SpawnableEnemyWithRarity> enemies = newLevel.Enemies;
				List<SpawnableEnemyWithRarity> list = new List<SpawnableEnemyWithRarity>(enemies.Count);
				list.AddRange(enemies);
				List<SpawnableEnemyWithRarity> value = list;
				Plugin.levelEnemySpawns.Add(newLevel, value);
			}
			Plugin.levelEnemySpawns.TryGetValue(newLevel, out var value2);
			newLevel.Enemies = value2;
			foreach (SpawnableEnemyWithRarity enemy in newLevel.Enemies)
			{
				Plugin.mls.LogInfo((object)("Inside: " + enemy.enemyType.enemyName));
				if (!Plugin.enemyRaritys.ContainsKey(enemy))
				{
					Plugin.enemyRaritys.Add(enemy, enemy.rarity);
				}
				Plugin.enemyRaritys.TryGetValue(enemy, out var value3);
				enemy.rarity = value3;
			}
			foreach (SpawnableEnemyWithRarity outsideEnemy in newLevel.OutsideEnemies)
			{
				Plugin.mls.LogInfo((object)("Outside: " + outsideEnemy.enemyType.enemyName));
				if (!Plugin.enemyRaritys.ContainsKey(outsideEnemy))
				{
					Plugin.enemyRaritys.Add(outsideEnemy, outsideEnemy.rarity);
				}
				Plugin.enemyRaritys.TryGetValue(outsideEnemy, out var value4);
				outsideEnemy.rarity = value4;
			}
			foreach (SpawnableEnemyWithRarity enemy2 in newLevel.Enemies)
			{
				if (!Plugin.enemyPropCurves.ContainsKey(enemy2))
				{
					Plugin.enemyPropCurves.Add(enemy2, enemy2.enemyType.probabilityCurve);
				}
				AnimationCurve value5 = new AnimationCurve();
				Plugin.enemyPropCurves.TryGetValue(enemy2, out value5);
				enemy2.enemyType.probabilityCurve = value5;
			}
			bool flag = false;
			foreach (SpawnableEnemyWithRarity enemy3 in newLevel.Enemies)
			{
				enemy3.rarity = 0;
				if (enemy3.enemyType.enemyName.ToLower().Contains("jester"))
				{
					Plugin.mls.LogInfo((object)"Found a jester, yoinking that reference");
					flag = true;
					Plugin.jesterRef = enemy3;
				}
			}
			if (!flag)
			{
				if (Plugin.jesterRef != null)
				{
					Plugin.mls.LogInfo((object)"Didn't find a jester, but we can use the ref");
					newLevel.Enemies.Add(Plugin.jesterRef);
				}
				else
				{
					Plugin.mls.LogInfo((object)"We couldn't add a jester to this level");
				}
			}
			foreach (SpawnableEnemyWithRarity outsideEnemy2 in newLevel.OutsideEnemies)
			{
				outsideEnemy2.rarity = 0;
			}
			SelectableLevel val = ScriptableObjectExtension.Clone<SelectableLevel>(newLevel);
			SpawnableMapObject[] spawnableMapObjects = val.spawnableMapObjects;
			for (int i = 0; i < spawnableMapObjects.Length; i++)
			{
				_ = (Object)(object)spawnableMapObjects[i].prefabToSpawn.GetComponentInChildren<Landmine>() != (Object)null;
			}
			newLevel = val;
			return true;
		}

		[HarmonyPatch(typeof(RoundManager), "AdvanceHourAndSpawnNewBatchOfEnemies")]
		[HarmonyPrefix]
		private static void updateCurrentLevelInfo(ref EnemyVent[] ___allEnemyVents, ref SelectableLevel ___currentLevel)
		{
			Plugin.currentLevel = ___currentLevel;
			Plugin.currentLevelVents = ___allEnemyVents;
		}

		[HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")]
		[HarmonyPrefix]
		private static void GameMasterCommands(HUDManager __instance)
		{
			string text = __instance.chatTextField.text;
			Plugin.mls.LogInfo((object)text);
			Plugin.commandHandler = new CommandHandler();
			if (Plugin.commandHandler.HandleCommand(text))
			{
				__instance.chatTextField.text = "";
			}
		}

		[HarmonyPatch(typeof(RoundManager), "SpawnEnemyFromVent")]
		[HarmonyPrefix]
		private static void logSpawnEnemyFromVent()
		{
			Plugin.mls.LogInfo((object)"Attempting to spawn an enemy");
		}

		[HarmonyPatch(typeof(RoundManager), "EnemyCannotBeSpawned")]
		[HarmonyPrefix]
		private static bool OverrideCannotSpawn()
		{
			return false;
		}
	}
}
namespace ExampleEnemy.Configuration
{
	public class PluginConfig
	{
		public ConfigEntry<int> SpawnWeight;

		public PluginConfig(BaseUnityPlugin plugin)
		{
			SpawnWeight = plugin.Config.Bind<int>("ExampleEnemy", "Spawn weight", 100, "The spawn chance weight for ExampleEnemy, relative to other existing enemies.\nGoes up from 0, lower is more rare, 100 and up is very common.");
			ClearUnusedEntries(plugin);
		}

		private void ClearUnusedEntries(BaseUnityPlugin plugin)
		{
			((Dictionary<ConfigDefinition, string>)((object)plugin.Config).GetType().GetProperty("OrphanedEntries", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(plugin.Config, null)).Clear();
			plugin.Config.Save();
		}
	}
}
namespace ExampleEnemy.Commands
{
	public class BuyItemsCommand : ICommand
	{
		private readonly List<string> itemList = new List<string>(12)
		{
			"Walkie-Talkie", "Pro Flashlight", "Normal Flashlight", "Shovel", "Lockpicker", "Stun Grenade", "Boom Box", "Inhaler", "Stun Gun", "Jet Pack",
			"Extension Ladder", "Radar Booster"
		};

		private readonly Dictionary<string, int> itemID = new Dictionary<string, int>
		{
			{ "Walkie-Talkie", 0 },
			{ "Pro Flashlight", 4 },
			{ "Normal Flashlight", 1 },
			{ "Shovel", 2 },
			{ "Lockpicker", 3 },
			{ "Stun Grenade", 5 },
			{ "Boom Box", 6 },
			{ "Inhaler", 7 },
			{ "Stun Gun", 8 },
			{ "Jet Pack", 9 },
			{ "Extension Ladder", 10 },
			{ "Radar Booster", 11 }
		};

		public string Name => "buy";

		public List<ArgumentModel> Args => new List<ArgumentModel>(2)
		{
			new ArgumentModel
			{
				Name = "itemName",
				ArgType = typeof(string)
			},
			new ArgumentModel
			{
				Name = "itemCount",
				ArgType = typeof(int),
				Optional = true
			}
		};

		public void Execute(string[] args)
		{
			string text = "Item Buying";
			string text2 = "";
			Terminal val = Object.FindObjectOfType<Terminal>();
			if ((Object)(object)val != (Object)null && args.Length != 0)
			{
				if (args[0] == "?")
				{
					HUDManager.Instance.AddTextToChatOnServer("List of Items:\n" + string.Join("\n", itemList), -1);
					return;
				}
				bool flag = false;
				if (args.Length > 1)
				{
					if (!int.TryParse(args[1], out var result))
					{
						return;
					}
					foreach (string item in itemList)
					{
						if (item.ToLower().Contains(args[0]))
						{
							flag = true;
							List<int> list = (from _ in Enumerable.Range(0, result)
								select itemID[item]).ToList();
							val.BuyItemsServerRpc(list.ToArray(), val.groupCredits, 0);
							text2 = $"Bought {result} {item}s";
							break;
						}
					}
					if (!flag)
					{
						return;
					}
				}
				if (!flag)
				{
					bool flag2 = false;
					foreach (string item2 in itemList)
					{
						if (item2.ToLower().Contains(args[0]))
						{
							flag2 = true;
							int[] array = new int[1] { itemID[item2] };
							val.BuyItemsServerRpc(array, val.groupCredits, 0);
							text2 = "Bought 1 " + item2;
						}
					}
					if (!flag2)
					{
						text2 = "No item found with that name";
					}
				}
			}
			HUDManager.Instance.DisplayTip(text, text2, false, false, "LC_Tip1");
		}
	}
	public class CommandHandler
	{
		private readonly List<ICommand> commands = new List<ICommand>();

		private readonly string _prefix;

		public CommandHandler(string prefix = "/")
		{
			_prefix = prefix;
			RegisterCommand(new HelpCommand());
			RegisterCommand(new MoneyCommand());
			RegisterCommand(new SpawnCommand());
			RegisterCommand(new ToggleLightsCommand());
			RegisterCommand(new BuyItemsCommand());
			RegisterCommand(new GodModeCommand());
			RegisterCommand(new NightVisionCommand());
			RegisterCommand(new SpeedHackCommand());
		}

		public List<ICommand> GetRegisteredCommands()
		{
			return commands;
		}

		public bool HandleCommand(string commandText)
		{
			if (!commandText.StartsWith(_prefix))
			{
				return false;
			}
			if (!Plugin.isHost)
			{
				HUDManager.Instance.DisplayTip("Command", "Unable to send command since you are not host.", false, false, "LC_Tip1");
				return true;
			}
			string text = commandText;
			int length = _prefix.Length;
			commandText = text.Substring(length, text.Length - length);
			string[] array = commandText.ToLower().Split(' ', StringSplitOptions.RemoveEmptyEntries);
			string commandName = array[0];
			ICommand command = null;
			foreach (ICommand command2 in commands)
			{
				if (command2.Name.ToLower() == commandName || command2.Aliases.Any((string a) => a.ToLower() == commandName))
				{
					command = command2;
					break;
				}
			}
			if (command != null)
			{
				string[] args = array.Skip(1).ToArray();
				if (command.HasRequiredArgs(args))
				{
					command.Execute(args);
				}
			}
			else
			{
				HUDManager.Instance.DisplayTip("Invalid", "Command not found", false, false, "LC_Tip1");
			}
			return true;
		}

		private void RegisterCommand(ICommand command)
		{
			commands.Add(command);
		}
	}
	public interface ICommand
	{
		string Name { get; }

		List<string> Aliases => new List<string>();

		List<ArgumentModel> Args => new List<ArgumentModel>();

		void Execute(string[] args);

		bool HasRequiredArgs(string[] args)
		{
			List<string> list = new List<string>();
			List<string> list2 = new List<string>();
			for (int i = 0; i < Args.AsQueryable().Count(); i++)
			{
				if (args.Length < i + 1 || string.IsNullOrEmpty(args[i]))
				{
					if (!Args[i].Optional)
					{
						list.Add(Args[i].Name);
					}
					continue;
				}
				string value = args[i];
				Type argType = Args[i].ArgType;
				try
				{
					Convert.ChangeType(value, argType);
				}
				catch (Exception)
				{
					list2.Add(Args[i].Name);
				}
			}
			if (list2.Any())
			{
				HUDManager.Instance.DisplayTip("Invalid", "Wrong input for Arguments: " + string.Join(", ", list2), false, false, "LC_Tip1");
			}
			else if (list.Any())
			{
				HUDManager.Instance.DisplayTip("Invalid", "Missing Arguments: " + string.Join(", ", list), false, false, "LC_Tip1");
			}
			if (!list.Any())
			{
				return !list2.Any();
			}
			return false;
		}
	}
	public class GodModeCommand : ICommand
	{
		public string Name => "god";

		public void Execute(string[] args)
		{
			Plugin.godMode = !Plugin.godMode;
			if (args.Length != 0)
			{
				float.Parse(args[0]);
			}
			if (Plugin.speedHack)
			{
				GameNetworkManager.Instance.localPlayerController.health = 1000000;
				GameNetworkManager.Instance.localPlayerController.healthRegenerateTimer = 0.1f;
			}
			else
			{
				GameNetworkManager.Instance.localPlayerController.health = 100;
				GameNetworkManager.Instance.localPlayerController.healthRegenerateTimer = 0f;
			}
			Console.WriteLine(GameNetworkManager.Instance.localPlayerController.healthRegenerateTimer);
			HUDManager.Instance.DisplayTip("God mode", "God mode set to: " + Plugin.godMode, false, false, "LC_Tip1");
		}
	}
	public class HelpCommand : ICommand
	{
		public string Name => "help";

		public List<string> Aliases => new List<string>(3) { "?", "commands", "info" };

		public void Execute(string[] args)
		{
			List<ICommand> registeredCommands = Plugin.commandHandler.GetRegisteredCommands();
			string text = string.Join("\n", registeredCommands.Select((ICommand m) => m.Name));
			HUDManager.Instance.AddTextToChatOnServer("List of Commands:\n" + text, -1);
		}
	}
	public class ArgumentModel
	{
		public Func<string, bool> Validate { get; set; } = (string argument) => true;


		public string Name { get; set; }

		public Type ArgType { get; set; }

		public bool Optional { get; set; }
	}
	public class MoneyCommand : ICommand
	{
		public string Name => "money";

		public List<string> Aliases => new List<string>(2) { "credits", "credit" };

		public List<ArgumentModel> Args => new List<ArgumentModel>(1)
		{
			new ArgumentModel
			{
				Name = "moneyAmount",
				ArgType = typeof(int)
			}
		};

		public void Execute(string[] args)
		{
			Terminal val = Object.FindObjectOfType<Terminal>();
			if (args.Length != 0)
			{
				val.groupCredits = int.Parse(args[0]);
				HUDManager.Instance.DisplayTip("Credits Command", "Set Terminal money to " + args[0], false, false, "LC_Tip1");
			}
		}
	}
	public class NightVisionCommand : ICommand
	{
		public string Name => "nightvision";

		public void Execute(string[] args)
		{
			Plugin.nightVision = !Plugin.nightVision;
			string text = "Night Vision";
			string text2 = (Plugin.nightVision ? "Enabled Night Vision" : "Disabled Night Vision");
			Plugin.hasGUISynced = false;
			HUDManager.Instance.DisplayTip(text, text2, false, false, "LC_Tip1");
		}
	}
	public class SpawnCommand : ICommand
	{
		public string Name => "spawn";

		public List<ArgumentModel> Args => new List<ArgumentModel>(3)
		{
			new ArgumentModel
			{
				Name = "enemyName",
				ArgType = typeof(string)
			},
			new ArgumentModel
			{
				Name = "enemyCount",
				ArgType = typeof(int),
				Optional = true
			},
			new ArgumentModel
			{
				Name = "playerToSpawnOn",
				ArgType = typeof(string),
				Optional = true
			}
		};

		public void Execute(string[] args)
		{
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Plugin.currentLevel == (Object)null)
			{
				HUDManager.Instance.DisplayTip("Invalid", "You can't spawn enemies in space", false, false, "LC_Tip1");
				return;
			}
			string text = "Spawned Enemies";
			string text2 = "";
			bool flag = false;
			string arg = "";
			int num = 1;
			string text3 = string.Join("\n", Plugin.currentLevel.Enemies.Select((SpawnableEnemyWithRarity m) => m.enemyType.enemyName).AsQueryable());
			List<List<SpawnableEnemyWithRarity>> list = new List<List<SpawnableEnemyWithRarity>>
			{
				Plugin.currentLevel.Enemies,
				Plugin.currentLevel.OutsideEnemies
			};
			List<string> list2 = new List<string>(3) { "?", "help", "" };
			if (args.Length == 1 && list2.Contains(args[0]))
			{
				HUDManager.Instance.AddTextToChatOnServer("List of Enemies:\n " + text3, -1);
				return;
			}
			Vector3? playerPosition = null;
			PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts;
			if (args.Length > 2)
			{
				PlayerControllerB[] array = allPlayerScripts;
				foreach (PlayerControllerB val in array)
				{
					if (val.playerUsername.ToLower().Contains(args[2].ToLower()))
					{
						playerPosition = ((Component)val).transform.position;
						break;
					}
					if (args[2].ToLower() == "@me" && val.playerUsername.ToLower().Contains(HUDManager.Instance.localPlayer.playerUsername.ToLower()))
					{
						playerPosition = ((Component)val).transform.position;
						break;
					}
				}
			}
			foreach (List<SpawnableEnemyWithRarity> item in list)
			{
				foreach (SpawnableEnemyWithRarity item2 in item)
				{
					if (!item2.enemyType.enemyName.ToLower().Contains(args[0].ToLower()))
					{
						continue;
					}
					try
					{
						flag = true;
						arg = item2.enemyType.enemyName;
						num = ((args.Length <= 1 || !int.TryParse(args[1], out var result)) ? 1 : result);
						if (playerPosition.HasValue)
						{
							Plugin.SpawnEnemy(item2, num, item == Plugin.currentLevel.Enemies, playerPosition);
						}
						else
						{
							Plugin.SpawnEnemy(item2, num, item == Plugin.currentLevel.Enemies);
						}
					}
					catch (Exception)
					{
					}
					text2 = $"Spawned {num}: {arg}";
					break;
				}
				if (flag)
				{
					break;
				}
			}
			HUDManager.Instance.DisplayTip(text, text2, false, false, "LC_Tip1");
			if (!flag)
			{
				HUDManager.Instance.DisplayTip("Invalid", "Failed to spawn enemies, check your command.", false, false, "LC_Tip1");
			}
		}

		private static bool ConvertToBoolean(string input, out bool output)
		{
			string[] array = new string[4] { "true", "1", "yes", "y" };
			input = input.Trim().ToLower();
			if (Array.Exists(array, (string value) => value == input))
			{
				output = true;
				return output;
			}
			output = false;
			return output;
		}
	}
	public class SpeedHackCommand : ICommand
	{
		public string Name => "speed";

		public List<ArgumentModel> Args => new List<ArgumentModel>(1)
		{
			new ArgumentModel
			{
				Name = "speedAmount",
				ArgType = typeof(double),
				Optional = true
			}
		};

		public void Execute(string[] args)
		{
			if (args.Length != 0)
			{
				Plugin.speedHack = true;
			}
			else
			{
				Plugin.speedHack = !Plugin.speedHack;
			}
			float num = ((args.Length != 0) ? float.Parse(args[0]) : 10f);
			if (Plugin.speedHack)
			{
				GameNetworkManager.Instance.localPlayerController.movementSpeed = num;
				HUDManager.Instance.DisplayTip("Speed hack", $"Speed set to: {num}", false, false, "LC_Tip1");
			}
			else
			{
				GameNetworkManager.Instance.localPlayerController.movementSpeed = 4.6f;
				HUDManager.Instance.DisplayTip("Speed hack", "Speed disabled", false, false, "LC_Tip1");
			}
		}
	}
	public class ToggleLightsCommand : ICommand
	{
		public string Name => "togglelights";

		public void Execute(string[] args)
		{
			string text = "";
			string text2 = "";
			BreakerBox val = Object.FindObjectOfType<BreakerBox>();
			if ((Object)(object)val != (Object)null)
			{
				text = "Light Change";
				if (val.isPowerOn)
				{
					Plugin.currentRound.TurnBreakerSwitchesOff();
					Plugin.currentRound.TurnOnAllLights(false);
					val.isPowerOn = false;
					text2 = "Turned the lights off";
				}
				else
				{
					Plugin.currentRound.PowerSwitchOnClientRpc();
					text2 = "Turned the lights on";
				}
			}
			HUDManager.Instance.DisplayTip(text, text2, false, false, "LC_Tip1");
		}
	}
}
namespace ExampleEnemy.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}