Decompiled source of PurgatorioEnemies v1.2.2

PurgSpawnArm/PurgSpawnArm.dll

Decompiled 10 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PluginConfig.API;
using PluginConfig.API.Fields;
using PurgSpawnArm;
using PurgatorioCyberGrind.Systems;
using UnityEngine;
using UnityEngine.AddressableAssets;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("PurgSpawnArm")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b3511d57436ffe975090530b4651304d19e5d42f")]
[assembly: AssemblyProduct("PurgSpawnArm")]
[assembly: AssemblyTitle("PurgSpawnArm")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PurgSpawnArm
{
	[HarmonyPatch]
	[BepInPlugin("purg.PurgSpawnArm", "Purg Spawn Arm", "1.2.2")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		private const string GUID = "purg.PurgSpawnArm";

		private static Harmony _harmony;

		public static SpawnableObject[] spawnableObjects;

		public static SpawnableObjectsDatabase CGIconsDatabase = new SpawnableObjectsDatabase();

		public static AssetBundle bundle;

		private static AssetBundle shadersBundle;

		private static List<Shader> loadedShaders;

		public static List<AudioSource> loadedAudioSources;

		public const string bundleName = "purg-indulgenceenemies";

		private PluginConfigurator config;

		public static BoolField CravenInCybergrind;

		public static BoolField NeutralizerInCybergrind;

		private void Start()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Expected O, but got Unknown
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Expected O, but got Unknown
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Invalid comparison between Unknown and I4
			config = PluginConfigurator.Create("Purgatorio Enemies", "purg.PurgSpawnArm");
			CravenInCybergrind = new BoolField(config.rootPanel, "Craven in the Cybergrind", "CravenInCybergrind", true);
			NeutralizerInCybergrind = new BoolField(config.rootPanel, "Neutralizer in the Cybergrind", "NeutralizerInCybergrind", true);
			config.SetIconWithURL("file://" + Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "plugin-icon.png"));
			bundle = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "purg-indulgenceenemies"));
			spawnableObjects = bundle.LoadAllAssets<SpawnableObject>();
			loadedAudioSources = bundle.LoadAllAssets<AudioSource>().ToList();
			CybergrindEntryLoader.RegisterAllEntries();
			_harmony = new Harmony("purg.PurgSpawnArm");
			_harmony.PatchAll();
			CGIconsDatabase.enemies = (SpawnableObject[])(object)new SpawnableObject[0];
			List<SpawnableObject> list = new List<SpawnableObject>();
			SpawnableObject[] array = spawnableObjects;
			foreach (SpawnableObject val in array)
			{
				if ((int)val.spawnableObjectType == 1)
				{
					list.Add(val);
				}
			}
			CGIconsDatabase.enemies = list.ToArray();
		}

		private static void SwapShader(Material material, Shader shader)
		{
			int renderQueue = material.renderQueue;
			material.shader = shader;
			material.renderQueue = renderQueue;
		}

		[HarmonyPatch(typeof(SpawnMenu), "RebuildMenu")]
		[HarmonyPrefix]
		private static void RebuildMenu(SpawnMenu __instance)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Invalid comparison between Unknown and I4
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			if (SceneHelper.IsPlayingCustom)
			{
				return;
			}
			List<SpawnableObject> list = __instance.objects.enemies.ToList();
			List<SpawnableObject> list2 = __instance.objects.objects.ToList();
			SpawnableObject[] array = spawnableObjects;
			foreach (SpawnableObject val in array)
			{
				val.sandboxOnly = false;
				if ((int)val.spawnableObjectType == 1 && !__instance.objects.enemies.Contains(val))
				{
					list.Add(val);
				}
				if ((int)val.spawnableObjectType == 0 && !__instance.objects.objects.Contains(val))
				{
					list2.Add(val);
				}
			}
			__instance.objects.enemies = list.ToArray();
			__instance.objects.objects = list2.ToArray();
		}
	}
	public static class Utils
	{
		public static void StlocIndex(this CodeInstruction self, out object index)
		{
			index = -1;
			if (CodeInstructionExtensions.IsStloc(self, (LocalBuilder)null))
			{
				OpCode opcode = self.opcode;
				switch (opcode.Name)
				{
				case "stloc.0":
					index = 0;
					break;
				case "stloc.1":
					index = 1;
					break;
				case "stloc.2":
					index = 2;
					break;
				case "stloc.3":
					index = 3;
					break;
				case "stloc":
				case "stloc.s":
					index = self.operand;
					break;
				}
			}
		}

		public static void LdlocIndex(this CodeInstruction self, out object index)
		{
			index = -1;
			if (CodeInstructionExtensions.IsLdloc(self, (LocalBuilder)null))
			{
				OpCode opcode = self.opcode;
				switch (opcode.Name)
				{
				case "ldloc.0":
					index = 0;
					break;
				case "ldloc.1":
					index = 1;
					break;
				case "ldloc.2":
					index = 2;
					break;
				case "ldloc.3":
					index = 3;
					break;
				case "ldloc":
				case "ldloc.s":
					index = self.operand;
					break;
				}
			}
		}
	}
}
namespace PurgatorioCyberGrind.Systems
{
	public abstract class CustomCyberGrindEntry
	{
		public abstract class SpawnTypePosition
		{
			public virtual int spawnTypeIndex { get; internal set; }

			public virtual CybergrindSpawnType spawnType { get; internal set; }
		}

		public class AfterSpawnTypeEnemy : SpawnTypePosition
		{
			public AfterSpawnTypeEnemy(CybergrindEnemyCatagories.MeleeEnemies afterMeleeEnemy)
			{
				spawnType = CybergrindSpawnType.melee;
				spawnTypeIndex = (int)afterMeleeEnemy;
			}

			public AfterSpawnTypeEnemy(CybergrindEnemyCatagories.ProjectileEnemies afterMeleeEnemy)
			{
				spawnType = CybergrindSpawnType.projectile;
				spawnTypeIndex = (int)afterMeleeEnemy;
			}

			public AfterSpawnTypeEnemy(CybergrindEnemyCatagories.UncommonEnemies afterMeleeEnemy)
			{
				spawnType = CybergrindSpawnType.uncommon;
				spawnTypeIndex = (int)afterMeleeEnemy;
			}

			public AfterSpawnTypeEnemy(CybergrindEnemyCatagories.SpecialEnemies afterMeleeEnemy)
			{
				spawnType = CybergrindSpawnType.special;
				spawnTypeIndex = (int)afterMeleeEnemy;
			}
		}

		public class BeforeSpawnTypeEnemy : SpawnTypePosition
		{
			public BeforeSpawnTypeEnemy(CybergrindEnemyCatagories.MeleeEnemies afterMeleeEnemy)
			{
				spawnType = CybergrindSpawnType.melee;
				spawnTypeIndex = (int)(afterMeleeEnemy - 1);
			}

			public BeforeSpawnTypeEnemy(CybergrindEnemyCatagories.ProjectileEnemies afterMeleeEnemy)
			{
				spawnType = CybergrindSpawnType.projectile;
				spawnTypeIndex = (int)(afterMeleeEnemy - 1);
			}

			public BeforeSpawnTypeEnemy(CybergrindEnemyCatagories.UncommonEnemies afterMeleeEnemy)
			{
				spawnType = CybergrindSpawnType.uncommon;
				spawnTypeIndex = (int)(afterMeleeEnemy - 1);
			}

			public BeforeSpawnTypeEnemy(CybergrindEnemyCatagories.SpecialEnemies afterMeleeEnemy)
			{
				spawnType = CybergrindSpawnType.special;
				spawnTypeIndex = (int)(afterMeleeEnemy - 1);
			}
		}

		public class AfterAllEnemies : SpawnTypePosition
		{
			public AfterAllEnemies(CybergrindSpawnType SpawnType)
			{
				spawnType = SpawnType;
				spawnTypeIndex = SpawnType switch
				{
					CybergrindSpawnType.melee => 5, 
					CybergrindSpawnType.projectile => 4, 
					CybergrindSpawnType.uncommon => 4, 
					CybergrindSpawnType.special => 2, 
					_ => 0, 
				};
			}
		}

		public class BeforeAllEnemies : SpawnTypePosition
		{
			public BeforeAllEnemies(CybergrindSpawnType SpawnType)
			{
				spawnType = SpawnType;
				spawnTypeIndex = SpawnType switch
				{
					CybergrindSpawnType.melee => 0, 
					CybergrindSpawnType.projectile => 0, 
					CybergrindSpawnType.uncommon => 0, 
					CybergrindSpawnType.special => 0, 
					_ => 0, 
				} - 1;
			}
		}

		internal virtual void Register()
		{
			CybergrindEntryLoader.ReserveEntryID();
			CybergrindEntryLoader.entries.Add(this);
		}

		public virtual bool AddedToTheCybergrind()
		{
			return true;
		}

		public virtual int CapNonCommonEnemyAmount(int currentWave, int enemyAmount)
		{
			return enemyAmount;
		}

		public virtual bool? CanBeRadiant(EndlessEnemy target, int currentWave, int enemyAmount)
		{
			return null;
		}

		public virtual bool UncommonMeleePositionsOnly()
		{
			return false;
		}

		public abstract void SetEntrySettings(out int spawnCost, out int costIncreasePerSpawn, out int spawnWave, out string spawnObjectName);

		public abstract SpawnTypePosition SetTypePosition();
	}
	public class CybergrindEnemyCatagories
	{
		public enum MeleeEnemies
		{
			Filth,
			Schism,
			Streetcleaner,
			Cerberus,
			Swordsmachine,
			Mannequin
		}

		public enum ProjectileEnemies
		{
			Stray,
			Drone,
			Filth,
			MaliciousFace,
			Gutterman
		}

		public enum UncommonEnemies
		{
			Virtue,
			Stalker,
			Sentry,
			Idol,
			Guttertank
		}

		public enum SpecialEnemies
		{
			Mindflayer,
			Insurrectionist,
			Ferryman
		}
	}
	internal static class CybergrindEntryLoader
	{
		internal static int entryCount = 38;

		internal static readonly IList<CustomCyberGrindEntry> entries = new List<CustomCyberGrindEntry>();

		internal static int ReserveEntryID()
		{
			int result = entryCount;
			entryCount++;
			return result;
		}

		public static CustomCyberGrindEntry GetCustomEntry(int type)
		{
			return entries[type - 38];
		}

		public static void RegisterAllEntries()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				foreach (Type item in from type in assemblies[i].GetTypes()
					where type.IsSubclassOf(typeof(CustomCyberGrindEntry)) && !type.IsAbstract && !type.IsGenericType
					select type)
				{
					((CustomCyberGrindEntry)Activator.CreateInstance(item)).Register();
				}
			}
		}

		public static string GetEntryName(int entryID)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			string text = "";
			if (entryID < 38)
			{
				EnemyType val = (EnemyType)entryID;
				return ((object)(EnemyType)(ref val)).ToString();
			}
			return GetCustomEntry(entryID).GetType().Name;
		}
	}
	public enum CybergrindSpawnType
	{
		melee,
		projectile,
		uncommon,
		special
	}
}
namespace PurgatorioCyberGrind.Patches
{
	[HarmonyPatch(typeof(EndlessGrid))]
	public static class EndlessGridPatch
	{
		private static bool instanced;

		public const int totalVanillaEnemies = 38;

		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void EndlessGrid_Start(EndlessGrid __instance, ref PrefabDatabase ___prefabs)
		{
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Invalid comparison between Unknown and I4
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			if (instanced)
			{
				return;
			}
			instanced = true;
			if (CybergrindEntryLoader.entryCount == 38)
			{
				return;
			}
			for (int i = 38; i < CybergrindEntryLoader.entryCount; i++)
			{
				EndlessEnemy[] meleeEnemies = ___prefabs.meleeEnemies;
				EndlessEnemy[] projectileEnemies = ___prefabs.projectileEnemies;
				EndlessEnemy[] uncommonEnemies = ___prefabs.uncommonEnemies;
				EndlessEnemy[] specialEnemies = ___prefabs.specialEnemies;
				int num = meleeEnemies.Length;
				int num2 = projectileEnemies.Length;
				int num3 = uncommonEnemies.Length;
				int num4 = specialEnemies.Length;
				CustomCyberGrindEntry customEntry = CybergrindEntryLoader.GetCustomEntry(i);
				if (!customEntry.AddedToTheCybergrind())
				{
					continue;
				}
				CustomCyberGrindEntry.SpawnTypePosition spawnTypePosition = customEntry.SetTypePosition();
				int num5 = spawnTypePosition.spawnType switch
				{
					CybergrindSpawnType.melee => num + 1, 
					CybergrindSpawnType.projectile => num2 + 1, 
					CybergrindSpawnType.uncommon => num3 + 1, 
					CybergrindSpawnType.special => num4 + 1, 
					_ => 0, 
				};
				EndlessEnemy[] array = (EndlessEnemy[])(object)new EndlessEnemy[num5];
				int num6 = 0;
				for (int j = 0; j < num5; j++)
				{
					if (spawnTypePosition.spawnTypeIndex + 1 != j)
					{
						EndlessEnemy[] array2 = array;
						int num7 = j;
						array2[num7] = (EndlessEnemy)(spawnTypePosition.spawnType switch
						{
							CybergrindSpawnType.melee => meleeEnemies[num6], 
							CybergrindSpawnType.projectile => projectileEnemies[num6], 
							CybergrindSpawnType.uncommon => uncommonEnemies[num6], 
							CybergrindSpawnType.special => specialEnemies[num6], 
							_ => meleeEnemies[num6], 
						});
						num6++;
						continue;
					}
					customEntry.SetEntrySettings(out int spawnCost, out int costIncreasePerSpawn, out int spawnWave, out string spawnObjectName);
					EndlessEnemy val = ScriptableObject.CreateInstance<EndlessEnemy>();
					((Object)val).name = customEntry.GetType().Name + "EndlessData";
					val.spawnCost = spawnCost;
					val.spawnWave = spawnWave;
					val.costIncreasePerSpawn = costIncreasePerSpawn;
					val.enemyType = (EnemyType)i;
					val.prefab = Plugin.bundle.LoadAsset<GameObject>(spawnObjectName);
					SpawnableObject[] spawnableObjects = Plugin.spawnableObjects;
					foreach (SpawnableObject val2 in spawnableObjects)
					{
						if ((int)val2.spawnableObjectType == 1 && ((Object)val2).name == spawnObjectName)
						{
							val.prefab = val2.gameObject;
							Vector3 position = val.prefab.transform.position;
							position.y = val2.spawnOffset;
							val.prefab.transform.position = position;
							break;
						}
					}
					array[j] = val;
				}
				switch (spawnTypePosition.spawnType)
				{
				case CybergrindSpawnType.melee:
					___prefabs.meleeEnemies = array;
					break;
				case CybergrindSpawnType.projectile:
					___prefabs.projectileEnemies = array;
					break;
				case CybergrindSpawnType.uncommon:
					___prefabs.uncommonEnemies = array;
					break;
				case CybergrindSpawnType.special:
					___prefabs.specialEnemies = array;
					break;
				}
				Logger.CreateLogSource("Purg Spawn Arm").Log((LogLevel)16, (object)("Added " + customEntry.GetType().Name + " to the cybergrind"));
			}
		}

		public static T Ass<T>(string path)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			return Addressables.LoadAssetAsync<T>((object)path).WaitForCompletion();
		}

		[HarmonyPatch("CapUncommonsAmount")]
		[HarmonyPostfix]
		public static void EndlessGrid_CapUncommonsAmount(int target, int amount, EndlessGrid __instance, ref int __result)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected I4, but got Unknown
			if ((int)__instance.prefabs.uncommonEnemies[target].enemyType >= 38)
			{
				__result = CybergrindEntryLoader.GetCustomEntry((int)__instance.prefabs.uncommonEnemies[target].enemyType).CapNonCommonEnemyAmount(__instance.currentWave, amount);
			}
		}

		[HarmonyPatch("SpawnRadiant")]
		[HarmonyPostfix]
		public static void EndlessGrid_SpawnRadiant(ref bool __result, EndlessEnemy target, int indexOf, EndlessGrid __instance)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected I4, but got Unknown
			if ((int)target.enemyType >= 38)
			{
				bool? flag = CybergrindEntryLoader.GetCustomEntry((int)target.enemyType).CanBeRadiant(target, __instance.currentWave, __instance.spawnedEnemyTypes[indexOf].amount);
				if (flag.HasValue)
				{
					__result = flag.Value;
				}
			}
		}

		[HarmonyPatch("SpawnUncommons")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> EndlessGrid_SpawnUncommons(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Expected O, but got Unknown
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Expected O, but got Unknown
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Expected O, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.Start().MatchForward(true, (CodeMatch[])(object)new CodeMatch[3]
			{
				new CodeMatch((OpCode?)OpCodes.Call, (object)typeof(Random).GetMethod("Range", new Type[2]
				{
					typeof(float),
					typeof(float)
				}), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldc_R4, (object)0.5f, (string)null),
				new CodeMatch((OpCode?)OpCodes.Cgt, (object)null, (string)null)
			}).ThrowIfInvalid("Could not locate the setting of the projectiles spawn pos only flag")
				.Advance(3);
			val.Instruction.StlocIndex(out object index);
			val.Advance(1).Insert((CodeInstruction[])(object)new CodeInstruction[5]
			{
				new CodeInstruction(OpCodes.Ldloc, index),
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Ldarg_1, (object)null),
				new CodeInstruction(OpCodes.Call, (object)typeof(EndlessGridPatch).GetMethod("SetProjPosSpawnFlag", BindingFlags.Static | BindingFlags.NonPublic)),
				new CodeInstruction(OpCodes.Stloc, index)
			}).ThrowIfInvalid("Could not inject setting of the proj positions flag");
			return val.InstructionEnumeration();
		}

		private static bool SetProjPosSpawnFlag(bool flag, EndlessGrid self, int target)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected I4, but got Unknown
			int num = (int)self.prefabs.uncommonEnemies[target].enemyType;
			if (num >= 38)
			{
				return !CybergrindEntryLoader.GetCustomEntry(num).UncommonMeleePositionsOnly();
			}
			return flag;
		}

		[HarmonyPatch("GetEnemies")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> EndlessGrid_GetEnemies(IEnumerable<CodeInstruction> instructions)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Expected O, but got Unknown
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Expected O, but got Unknown
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Expected O, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Expected O, but got Unknown
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Expected O, but got Unknown
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Expected O, but got Unknown
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Expected O, but got Unknown
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Expected O, but got Unknown
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Expected O, but got Unknown
			//IL_0217: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Expected O, but got Unknown
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0240: Expected O, but got Unknown
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Expected O, but got Unknown
			CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null);
			val.Start().MatchForward(false, (CodeMatch[])(object)new CodeMatch[8]
			{
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)typeof(PrefabDatabase).GetField("specialEnemies"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldelem_Ref, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)typeof(EndlessGrid).GetField("spawnCost"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Conv_R4, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Add, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Blt_Un, (object)null, (string)null)
			}).ThrowIfInvalid("Could not locate initial special enemies spawn cost check")
				.MatchForward(true, (CodeMatch[])(object)new CodeMatch[2]
				{
					new CodeMatch((OpCode?)OpCodes.Ldfld, (object)typeof(PrefabDatabase).GetField("specialEnemies"), (string)null),
					new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null)
				})
				.ThrowIfInvalid("Could not locate the getting of the special enemies index loc varnum");
			val.Instruction.LdlocIndex(out object index);
			val.MatchForward(true, (CodeMatch[])(object)new CodeMatch[6]
			{
				new CodeMatch((OpCode?)OpCodes.Ldelem_Ref, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldfld, (object)typeof(EndlessGrid).GetField("spawnCost"), (string)null),
				new CodeMatch((OpCode?)OpCodes.Conv_R4, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Ldloc_S, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Add, (object)null, (string)null),
				new CodeMatch((OpCode?)OpCodes.Blt_Un, (object)null, (string)null)
			}).ThrowIfInvalid("Could not locate the blt.un jump instruction after the special enemies spawn cost check");
			object operand = val.Operand;
			val.Advance(1).Insert((CodeInstruction[])(object)new CodeInstruction[4]
			{
				new CodeInstruction(OpCodes.Ldloc, index),
				new CodeInstruction(OpCodes.Ldarg_0, (object)null),
				new CodeInstruction(OpCodes.Call, (object)typeof(EndlessGridPatch).GetMethod("GetEnemiesCapSpecials", BindingFlags.Static | BindingFlags.NonPublic)),
				new CodeInstruction(OpCodes.Brfalse, operand)
			}).ThrowIfInvalid("Could not inject additional special enemies check");
			return val.InstructionEnumeration();
		}

		private static bool GetEnemiesCapSpecials(int num8, EndlessGrid self)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			int indexOfEnemyType = self.GetIndexOfEnemyType(self.prefabs.specialEnemies[num8].enemyType);
			return CapSpecialsAmount(num8, self.spawnedEnemyTypes[indexOfEnemyType].amount + 1, ref self.prefabs, self.currentWave) > self.spawnedEnemyTypes[indexOfEnemyType].amount;
		}

		public static int CapSpecialsAmount(int target, int amount, ref PrefabDatabase prefabs, int currentWave)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected I4, but got Unknown
			if ((int)prefabs.specialEnemies[target].enemyType >= 38)
			{
				return CybergrindEntryLoader.GetCustomEntry((int)prefabs.specialEnemies[target].enemyType).CapNonCommonEnemyAmount(currentWave, amount);
			}
			return amount;
		}

		private static void LogCybergrindEnemyEntries(PrefabDatabase prefabs)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Expected I4, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected I4, but got Unknown
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Expected I4, but got Unknown
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Expected I4, but got Unknown
			Logger.CreateLogSource("Purg Spawn Arm").Log((LogLevel)16, (object)"The following logs are each cybergrind type and their enemies listed");
			for (int i = 0; i < prefabs.meleeEnemies.Length; i++)
			{
				Logger.CreateLogSource("Purg Spawn Arm").Log((LogLevel)16, (object)("melee " + i + " type: " + CybergrindEntryLoader.GetEntryName((int)prefabs.meleeEnemies[i].enemyType)));
			}
			for (int j = 0; j < prefabs.projectileEnemies.Length; j++)
			{
				Logger.CreateLogSource("Purg Spawn Arm").Log((LogLevel)16, (object)("projectile " + j + " type: " + CybergrindEntryLoader.GetEntryName((int)prefabs.projectileEnemies[j].enemyType)));
			}
			for (int k = 0; k < prefabs.uncommonEnemies.Length; k++)
			{
				Logger.CreateLogSource("Purg Spawn Arm").Log((LogLevel)16, (object)("uncommon " + k + " type: " + CybergrindEntryLoader.GetEntryName((int)prefabs.uncommonEnemies[k].enemyType)));
			}
			for (int l = 0; l < prefabs.specialEnemies.Length; l++)
			{
				Logger.CreateLogSource("Purg Spawn Arm").Log((LogLevel)16, (object)("special " + l + " type: " + CybergrindEntryLoader.GetEntryName((int)prefabs.specialEnemies[l].enemyType)));
			}
		}
	}
}
namespace PurgatorioCyberGrind.CybergrindEntries
{
	public class CravenEntry : CustomCyberGrindEntry
	{
		public override bool AddedToTheCybergrind()
		{
			return Plugin.CravenInCybergrind.value;
		}

		public override void SetEntrySettings(out int spawnCost, out int costIncreasePerSpawn, out int spawnWave, out string spawnObjectName)
		{
			spawnCost = 20;
			costIncreasePerSpawn = 15;
			spawnWave = 18;
			spawnObjectName = "Craven";
		}

		public override SpawnTypePosition SetTypePosition()
		{
			return new BeforeAllEnemies(CybergrindSpawnType.uncommon);
		}
	}
	public class NeutralizerEntry : CustomCyberGrindEntry
	{
		public override bool AddedToTheCybergrind()
		{
			return Plugin.NeutralizerInCybergrind.value;
		}

		public override void SetEntrySettings(out int spawnCost, out int costIncreasePerSpawn, out int spawnWave, out string spawnObjectName)
		{
			spawnCost = 55;
			costIncreasePerSpawn = 0;
			spawnWave = 19;
			spawnObjectName = "Neutralizer";
		}

		public override SpawnTypePosition SetTypePosition()
		{
			return new AfterSpawnTypeEnemy(CybergrindEnemyCatagories.UncommonEnemies.Idol);
		}

		public override int CapNonCommonEnemyAmount(int currentWave, int enemyAmount)
		{
			return 1;
		}

		public override bool? CanBeRadiant(EndlessEnemy target, int currentWave, int enemyAmount)
		{
			return false;
		}

		public override bool UncommonMeleePositionsOnly()
		{
			return true;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}