Decompiled source of UKEnemyIdentifier v1.0.0

plugins/UKEnemyIdentifier/UKEnemyIdentifier.dll

Decompiled 4 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using UKEnemyIdentifier.Components;
using UKEnemyIdentifier.Utils;
using UnityEngine;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("UKEnemyIdentifier")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UKEnemyIdentifier")]
[assembly: AssemblyCopyright("Copyright ©  2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("23B65D15-307A-40B5-B785-189FDD449F1A")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace UKEnemyIdentifier
{
	[BepInProcess("ULTRAKILL.exe")]
	[BepInPlugin("dev.flazhik.ukenemyidentifier", "UKEnemyIdentifier", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private Harmony _harmony;

		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			_harmony = new Harmony("dev.flazhik.ukenemyidentifier");
			_harmony.PatchAll();
		}
	}
	internal static class PluginInfo
	{
		public const string GUID = "dev.flazhik.ukenemyidentifier";

		public const string NAME = "UKEnemyIdentifier";

		public const string VERSION = "1.0.0";
	}
}
namespace UKEnemyIdentifier.Utils
{
	public static class EnemyIdentifierExtension
	{
		private static readonly Dictionary<EnemyType, string> EnemyNamesDict = new Dictionary<EnemyType, string>
		{
			{
				(EnemyType)19,
				"Sisyphean Insurrectionist"
			},
			{
				(EnemyType)5,
				"Mindflayer"
			},
			{
				(EnemyType)26,
				"Ferryman"
			},
			{
				(EnemyType)2,
				"Hideous Mass"
			},
			{
				(EnemyType)7,
				"Swordsmachine"
			},
			{
				(EnemyType)33,
				"Gutterman"
			},
			{
				(EnemyType)34,
				"Guttertank"
			},
			{
				(EnemyType)31,
				"Mannequin"
			},
			{
				(EnemyType)0,
				"Cerberus"
			},
			{
				(EnemyType)1,
				"Drone"
			},
			{
				(EnemyType)4,
				"Malicious Face"
			},
			{
				(EnemyType)6,
				"Streetcleaner"
			},
			{
				(EnemyType)9,
				"Virtue"
			},
			{
				(EnemyType)12,
				"Stalker"
			},
			{
				(EnemyType)13,
				"Stray"
			},
			{
				(EnemyType)14,
				"Schism"
			},
			{
				(EnemyType)15,
				"Soldier"
			},
			{
				(EnemyType)20,
				"Turret"
			},
			{
				(EnemyType)3,
				"Filth"
			},
			{
				(EnemyType)21,
				"Idol"
			}
		};

		public static string GetEnemyName(this EnemyIdentifier value)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (!EnemyNamesDict.TryGetValue(value.enemyType, out var value2))
			{
				return "UNKNOWN ENTITY";
			}
			return value2;
		}
	}
	public static class ReflectionUtils
	{
		private const BindingFlags BindingFlagsFields = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;

		public static object GetPrivate<T>(T instance, Type classType, string field)
		{
			return classType.GetField(field, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).GetValue(instance);
		}

		public static IEnumerable<CodeInstruction> IL(params (OpCode, object)[] instructions)
		{
			return ((IEnumerable<(OpCode, object)>)instructions).Select((Func<(OpCode, object), CodeInstruction>)(((OpCode, object) i) => new CodeInstruction(i.Item1, i.Item2))).ToList();
		}
	}
}
namespace UKEnemyIdentifier.Patches
{
	[HarmonyPatch(typeof(ContinuousBeam))]
	public class ContinuousBeamPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(ContinuousBeam), "Update")]
		public static IEnumerable<CodeInstruction> ContinuousBeam_Update_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (InjectionPoint(list[i]))
				{
					SetBeamHurtingFactor(list, i);
					break;
				}
			}
			return list;
		}

		private static bool InjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Callvirt)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Method(typeof(NewMovement), "GetHurt", new Type[7]
				{
					typeof(int),
					typeof(bool),
					typeof(float),
					typeof(bool),
					typeof(bool),
					typeof(float),
					typeof(bool)
				}, (Type[])null));
			}
			return false;
		}

		private static void SetBeamHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Call, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Stfld, AccessTools.Field(typeof(EnemyIdentifierManager), "LastHurtingFactor"))));
		}
	}
	[HarmonyPatch(typeof(Drone))]
	public class DronePatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Drone), "SetProjectileSettings")]
		public static void Drone_SetProjectileSettings_Postfix(Projectile proj, EnemyIdentifier ___eid)
		{
			MonoSingleton<EnemyIdentifierManager>.Instance.RegisterFactor(((Component)proj).gameObject, ___eid);
		}
	}
	[HarmonyPatch(typeof(Explosion))]
	public class ExplosionPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Explosion), "Collide")]
		public static IEnumerable<CodeInstruction> Explosion_Collide_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			SetLastHurtingFactor(list, 0);
			return list;
		}

		private static bool InjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Callvirt)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Method(typeof(NewMovement), "GetHurt", new Type[7]
				{
					typeof(int),
					typeof(bool),
					typeof(float),
					typeof(bool),
					typeof(bool),
					typeof(float),
					typeof(bool)
				}, (Type[])null));
			}
			return false;
		}

		private static void SetLastHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Call, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Stfld, AccessTools.Field(typeof(EnemyIdentifierManager), "LastHurtingFactor"))));
		}
	}
	[HarmonyPatch(typeof(Ferryman))]
	public class FerrymanPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Ferryman), "SpawnLightningBolt")]
		public static IEnumerable<CodeInstruction> Ferryman_SpawnLightningBolt_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			SetProjectileHurtingFactor(list, list.Count - 1);
			return list;
		}

		private static void SetProjectileHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldloc_0, null), (OpCodes.Callvirt, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Ldfld, AccessTools.Field(typeof(Ferryman), "eid")), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "RegisterFactor", new Type[2]
			{
				typeof(GameObject),
				typeof(EnemyIdentifier)
			}, (Type[])null)), (OpCodes.Nop, null)));
		}
	}
	[HarmonyPatch(typeof(FinalCyberRank))]
	public class FinalCyberRankPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(FinalCyberRank), "Update")]
		public static IEnumerable<CodeInstruction> FinalCyberRank_Update_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (InjectionPoint(list[i]))
				{
					DisableCybergrindTimeFreeze(list, i);
					break;
				}
			}
			return list;
		}

		private static bool InjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Call)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Method(typeof(Time), "set_timeScale", new Type[1] { typeof(float) }, (Type[])null));
			}
			return false;
		}

		private static void DisableCybergrindTimeFreeze(List<CodeInstruction> instructions, int index)
		{
			instructions.RemoveRange(index - 7, 8);
		}
	}
	[HarmonyPatch(typeof(FireZone))]
	public class FireZonePatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(FireZone), "OnTriggerStay")]
		public static IEnumerable<CodeInstruction> FireZone_OnTriggerStay_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (InjectionPoint(list[i]))
				{
					SetFireHurtingFactor(list, i - 1);
					break;
				}
			}
			return list;
		}

		private static bool InjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Call)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Method(typeof(PlayerTracker), "get_Instance", (Type[])null, (Type[])null));
			}
			return false;
		}

		private static void SetFireHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Call, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Stfld, AccessTools.Field(typeof(EnemyIdentifierManager), "LastHurtingFactor"))));
		}
	}
	[HarmonyPatch(typeof(Gutterman))]
	public class GuttermanPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Gutterman), "FixedUpdate")]
		private static IEnumerable<CodeInstruction> Gutterman_Shoot_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (InjectionPoint(list[i]))
				{
					SetBeamLocalVariable(list, generator, i + 1);
					SetBeamHurtingFactor(list, i + 15);
					break;
				}
			}
			return list;
		}

		private static bool InjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Call)
			{
				return instruction.operand.ToString().Contains("Instantiate");
			}
			return false;
		}

		private static void SetBeamLocalVariable(List<CodeInstruction> instructions, ILGenerator generator, int index)
		{
			LocalBuilder item = generator.DeclareLocal(typeof(GameObject));
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Stloc_2, item), (OpCodes.Ldloc_2, null)));
		}

		private static void SetBeamHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldloc_2, null), (OpCodes.Ldarg_0, null), (OpCodes.Ldfld, AccessTools.Field(typeof(Gutterman), "eid")), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "RegisterFactor", new Type[2]
			{
				typeof(GameObject),
				typeof(EnemyIdentifier)
			}, (Type[])null)), (OpCodes.Nop, null)));
		}
	}
	[HarmonyPatch(typeof(LightningStrikeExplosive))]
	public class LightningStrikeExplosivePatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(LightningStrikeExplosive), "Start")]
		public static IEnumerable<CodeInstruction> LightningStrikeExplosive_SpawnLightningBolt_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (!(list[i].opcode != OpCodes.Stloc_S) && list[i].operand is LocalBuilder && ((LocalBuilder)list[i].operand).LocalIndex == 6)
				{
					LocalBuilder explosion = (LocalBuilder)list[i].operand;
					SetLightningExplosionHurtingFactor(list, explosion, i);
					break;
				}
			}
			return list;
		}

		private static void SetLightningExplosionHurtingFactor(List<CodeInstruction> instructions, LocalBuilder explosion, int index)
		{
			instructions.InsertRange(index + 1, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Ldloc_S, explosion), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "RegisterLightningStrikeExplosion", new Type[2]
			{
				typeof(LightningStrikeExplosive),
				typeof(Explosion)
			}, (Type[])null)), (OpCodes.Nop, null)));
		}
	}
	[HarmonyPatch(typeof(Mannequin))]
	public class MannequinPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Mannequin), "ShootProjectile")]
		public static IEnumerable<CodeInstruction> Mannequin_ShootProjectile_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (InjectionPoint(list[i]))
				{
					SetProjectileHurtingFactor(list, i);
					break;
				}
			}
			return list;
		}

		private static bool InjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Stfld)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Field(typeof(Projectile), "target"));
			}
			return false;
		}

		private static void SetProjectileHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldloc_0, null), (OpCodes.Callvirt, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Ldfld, AccessTools.Field(typeof(Mannequin), "eid")), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "RegisterFactor", new Type[2]
			{
				typeof(GameObject),
				typeof(EnemyIdentifier)
			}, (Type[])null)), (OpCodes.Nop, null)));
		}
	}
	[HarmonyPatch(typeof(Mass))]
	public class MassPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Mass), "ShootHoming")]
		private static IEnumerable<CodeInstruction> Mass_ShootHoming_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (InjectionPoint(list[i]))
				{
					SetProjectileHurtingFactor(list, i + 2, generator);
					break;
				}
			}
			return list;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Mass), "ShootExplosive")]
		private static IEnumerable<CodeInstruction> Mass_ShootExplosive_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (InjectionPoint(list[i]))
				{
					SetProjectileHurtingFactor(list, i + 2, generator);
					break;
				}
			}
			return list;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Mass), "ShootSpear")]
		private static void Mass_ShootSpear_Postfix(EnemyIdentifier ___eid, Mass __instance)
		{
			MassSpear val = default(MassSpear);
			if (__instance.tempSpear.TryGetComponent<MassSpear>(ref val))
			{
				MonoSingleton<EnemyIdentifierManager>.Instance.RegisterFactor(((Component)val).gameObject, ___eid);
			}
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Mass), "SlamImpact")]
		private static IEnumerable<CodeInstruction> Mass_SlamImpact_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			SetWaveHurtingFactor(list, list.Count - 1);
			return list;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Mass), "SwingEnd")]
		private static IEnumerable<CodeInstruction> Mass_SwingEnd_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			SetSwingEndWaveHurtingFactor(list, list.Count - 1);
			return list;
		}

		private static bool InjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Stfld)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Field(typeof(Projectile), "target"));
			}
			return false;
		}

		private static void SetWaveHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldloc_1, null), (OpCodes.Callvirt, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Ldfld, AccessTools.Field(typeof(Mass), "eid")), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "RegisterFactor", new Type[2]
			{
				typeof(GameObject),
				typeof(EnemyIdentifier)
			}, (Type[])null)), (OpCodes.Nop, null)));
		}

		private static void SetSwingEndWaveHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldloc_0, null), (OpCodes.Callvirt, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Ldfld, AccessTools.Field(typeof(Mass), "eid")), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "RegisterFactor", new Type[2]
			{
				typeof(GameObject),
				typeof(EnemyIdentifier)
			}, (Type[])null)), (OpCodes.Nop, null)));
		}

		private static void SetProjectileHurtingFactor(List<CodeInstruction> instructions, int index, ILGenerator generator)
		{
			LocalBuilder item = generator.DeclareLocal(typeof(Projectile));
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Stloc_S, item), (OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldloc_S, item), (OpCodes.Callvirt, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Ldfld, AccessTools.Field(typeof(Mass), "eid")), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "RegisterFactor", new Type[2]
			{
				typeof(GameObject),
				typeof(EnemyIdentifier)
			}, (Type[])null)), (OpCodes.Dup, null)));
		}
	}
	[HarmonyPatch(typeof(MassSpear))]
	public class MassSpearPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(MassSpear), "DelayedPlayerCheck")]
		private static bool Mass_ShootHoming_Prefix(bool ___deflected, MassSpear __instance)
		{
			if (___deflected)
			{
				return false;
			}
			MonoSingleton<EnemyIdentifierManager>.Instance.LastHurtingFactor = ((Component)__instance).gameObject;
			return true;
		}
	}
	[HarmonyPatch(typeof(Mindflayer))]
	public class MindflayerPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Mindflayer), "ShootProjectiles")]
		public static IEnumerable<CodeInstruction> Mindflayer_ShootProjectiles_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 2; i < list.Count; i++)
			{
				if (InjectionPoint(list[i - 2]))
				{
					RegisterProjectilesFactor(list, generator, i);
					break;
				}
			}
			return list;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Mindflayer), "StartBeam")]
		public static void Mindflayer_StartBeam_Postfix(EnemyIdentifier ___eid, Mindflayer __instance)
		{
			ContinuousBeam val = default(ContinuousBeam);
			if (__instance.tempBeam.TryGetComponent<ContinuousBeam>(ref val))
			{
				MonoSingleton<EnemyIdentifierManager>.Instance.RegisterFactor(((Component)val).gameObject, ___eid);
			}
		}

		private static bool InjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Stfld)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Field(typeof(Projectile), "target"));
			}
			return false;
		}

		private static void RegisterProjectilesFactor(List<CodeInstruction> instructions, ILGenerator generator, int index)
		{
			LocalBuilder item = generator.DeclareLocal(typeof(Projectile));
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Dup, null), (OpCodes.Stloc_3, item), (OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldloc_3, null), (OpCodes.Callvirt, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Ldfld, AccessTools.Field(typeof(Mindflayer), "eid")), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "RegisterFactor", new Type[2]
			{
				typeof(GameObject),
				typeof(EnemyIdentifier)
			}, (Type[])null)), (OpCodes.Nop, null)));
		}
	}
	[HarmonyPatch(typeof(NewMovement))]
	public class NewMovementPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(NewMovement), "GetHurt")]
		public static void NewMovement_GetHurt_Postfix(NewMovement __instance, int damage)
		{
			EnemyIdentifierManager instance = MonoSingleton<EnemyIdentifierManager>.Instance;
			if (!instance.DeadAlready && damage != 0)
			{
				EnemyIdentifier eid = instance.IdentifyEnemy();
				bool flag = __instance.hp == 0;
				if (flag)
				{
					instance.DeadAlready = true;
				}
				instance.PlayerHurt(eid, damage, flag);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(NewMovement), "Respawn")]
		public static void NewMovement_Respawn_Prefix(NewMovement __instance)
		{
			MonoSingleton<EnemyIdentifierManager>.Instance.DeadAlready = false;
		}
	}
	[HarmonyPatch(typeof(Explosion))]
	public class PhysicalShockwavePatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(PhysicalShockwave), "CheckCollision")]
		public static bool PhysicalShockwave_CheckCollision_Prefix(Collider col, PhysicalShockwave __instance)
		{
			if (!__instance.hasHurtPlayer && ((Component)col).gameObject.layer != 15 && ((Component)col).gameObject.CompareTag("Player"))
			{
				MonoSingleton<EnemyIdentifierManager>.Instance.LastHurtingFactor = ((Component)__instance).gameObject;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Projectile))]
	public class ProjectilePatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Projectile), "TimeToDie")]
		public static bool Projectile_TimeToDie_Prefix(Projectile __instance)
		{
			MonoSingleton<EnemyIdentifierManager>.Instance.LastHurtingFactor = ((Component)__instance).gameObject;
			return true;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Projectile), "Explode")]
		public static IEnumerable<CodeInstruction> Projectile_Explode_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return PatchExplosions(instructions);
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Projectile), "CreateExplosionEffect")]
		public static IEnumerable<CodeInstruction> Projectile_CreateExplosionEffect_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			return PatchExplosions(instructions);
		}

		private static IEnumerable<CodeInstruction> PatchExplosions(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (InjectionPoint(list[i]))
				{
					SetExplosionHurtingFactor(list, i + 1);
					break;
				}
			}
			return list;
		}

		private static bool InjectionPoint(CodeInstruction instruction)
		{
			return instruction.opcode == OpCodes.Stloc_2;
		}

		private static void SetExplosionHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Ldloc_2, null), (OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "GetIdentifierFor", new Type[1] { typeof(Projectile) }, (Type[])null)), (OpCodes.Stfld, AccessTools.Field(typeof(Explosion), "originEnemy"))));
		}
	}
	[HarmonyPatch(typeof(RevolverBeam))]
	public class RevolverBeamPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(RevolverBeam), "HitSomething")]
		public static IEnumerable<CodeInstruction> RevolverBeam_HitSomething_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (!(list[i].opcode != OpCodes.Stloc_S) && list[i].operand is LocalBuilder && ((LocalBuilder)list[i].operand).LocalIndex == 9)
				{
					LocalBuilder explosion = (LocalBuilder)list[i].operand;
					RegisterBeamExplosion(list, explosion, i);
					break;
				}
			}
			return list;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(RevolverBeam), "ExecuteHits")]
		public static IEnumerable<CodeInstruction> RevolverBeam_ExecuteHits_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (HurtingFactorInjectionPoint(list[i]))
				{
					SetBeamHurtingFactor(list, i);
					break;
				}
			}
			return list;
		}

		private static bool HurtingFactorInjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Callvirt)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Method(typeof(NewMovement), "GetHurt", new Type[7]
				{
					typeof(int),
					typeof(bool),
					typeof(float),
					typeof(bool),
					typeof(bool),
					typeof(float),
					typeof(bool)
				}, (Type[])null));
			}
			return false;
		}

		private static void SetBeamHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index - 13, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Call, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Stfld, AccessTools.Field(typeof(EnemyIdentifierManager), "LastHurtingFactor"))));
		}

		private static void RegisterBeamExplosion(List<CodeInstruction> instructions, LocalBuilder explosion, int index)
		{
			instructions.InsertRange(index + 1, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Ldloc_S, explosion), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "RegisterRevolverBeamExplosion", new Type[2]
			{
				typeof(RevolverBeam),
				typeof(Explosion)
			}, (Type[])null)), (OpCodes.Nop, null)));
		}
	}
	[HarmonyPatch(typeof(Sisyphus))]
	public class SisyphusPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Sisyphus), "FixedUpdate")]
		public static IEnumerable<CodeInstruction> StatueBoss_FixedUpdate_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (LandingWaveInjectionPoint(list[i]))
				{
					SetWaveHurtingFactor(list, i + 1);
					break;
				}
			}
			return list;
		}

		private static bool LandingWaveInjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Stfld)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Field(typeof(PhysicalShockwave), "speed"));
			}
			return false;
		}

		private static void SetWaveHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldloc_2, null), (OpCodes.Callvirt, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Ldfld, AccessTools.Field(typeof(Sisyphus), "eid")), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "RegisterFactor", new Type[2]
			{
				typeof(GameObject),
				typeof(EnemyIdentifier)
			}, (Type[])null)), (OpCodes.Nop, null)));
		}
	}
	[HarmonyPatch(typeof(SpiderBody))]
	public class SpiderBodyPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(SpiderBody), "ShootProj")]
		public static void SpiderBody_ShootProj_Postfix(GameObject ___currentProj, EnemyIdentifier ___eid)
		{
			MonoSingleton<EnemyIdentifierManager>.Instance.RegisterFactor(___currentProj.gameObject, ___eid);
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(SpiderBody), "BeamFire")]
		public static void SpiderBody_BeamFire_Postfix(GameObject ___currentBeam, EnemyIdentifier ___eid)
		{
			RevolverBeam val = default(RevolverBeam);
			if (!((Object)(object)___currentBeam == (Object)null) && ___currentBeam.TryGetComponent<RevolverBeam>(ref val))
			{
				MonoSingleton<EnemyIdentifierManager>.Instance.RegisterFactor(((Component)val).gameObject, ___eid);
			}
		}
	}
	[HarmonyPatch(typeof(EnemyShotgun))]
	public class EnemyShotgunPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(EnemyShotgun), "Fire")]
		public static IEnumerable<CodeInstruction> EnemyShotgun_Fire_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			LocalBuilder localBuilder = null;
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (ProjectileOperand(list[i]))
				{
					localBuilder = (LocalBuilder)list[i].operand;
				}
				if (InjectionPoint(list[i]))
				{
					if (localBuilder != null)
					{
						SetShotgunHurtingFactor(list, localBuilder, i);
					}
					break;
				}
			}
			return list;
		}

		private static bool InjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Stfld)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Field(typeof(Projectile), "spreaded"));
			}
			return false;
		}

		private static bool ProjectileOperand(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Ldloc_S && instruction.operand is LocalBuilder localBuilder)
			{
				return localBuilder.LocalType == typeof(Projectile);
			}
			return false;
		}

		private static void SetShotgunHurtingFactor(List<CodeInstruction> instructions, LocalBuilder projectile, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldloc_S, projectile), (OpCodes.Callvirt, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Ldfld, AccessTools.Field(typeof(EnemyShotgun), "eid")), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "RegisterFactor", new Type[2]
			{
				typeof(GameObject),
				typeof(EnemyIdentifier)
			}, (Type[])null)), (OpCodes.Nop, null)));
		}
	}
	[HarmonyPatch(typeof(StatueBoss))]
	public class StatueBossPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(StatueBoss), "OrbSpawn")]
		public static IEnumerable<CodeInstruction> StatueBoss_OrbSpawn_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (OrbSpawnInjectionPoint(list[i]))
				{
					SetOrbHurtingFactor(list, i + 1);
					break;
				}
			}
			return list;
		}

		[HarmonyTranspiler]
		[HarmonyPatch(typeof(StatueBoss), "StompHit")]
		public static IEnumerable<CodeInstruction> StatueBoss_StompHit_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (StompHitInjectionPoint(list[i]))
				{
					SetStompHitHurtingFactor(list, i + 1);
					break;
				}
			}
			return list;
		}

		private static bool OrbSpawnInjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Stfld)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Field(typeof(Projectile), "target"));
			}
			return false;
		}

		private static bool StompHitInjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Stfld)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Field(typeof(PhysicalShockwave), "enemyType"));
			}
			return false;
		}

		private static void SetOrbHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldloc_1, null), (OpCodes.Callvirt, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Ldfld, AccessTools.Field(typeof(StatueBoss), "eid")), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "RegisterFactor", new Type[2]
			{
				typeof(GameObject),
				typeof(EnemyIdentifier)
			}, (Type[])null)), (OpCodes.Nop, null)));
		}

		private static void SetStompHitHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldloc_2, null), (OpCodes.Callvirt, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Ldfld, AccessTools.Field(typeof(StatueBoss), "eid")), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "RegisterFactor", new Type[2]
			{
				typeof(GameObject),
				typeof(EnemyIdentifier)
			}, (Type[])null)), (OpCodes.Nop, null)));
		}
	}
	[HarmonyPatch(typeof(SwingCheck2))]
	public class SwingCheck2Patch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(SwingCheck2), "CheckCollision")]
		public static IEnumerable<CodeInstruction> SwingCheck2_CheckCollision_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (InjectionPoint(list[i]))
				{
					SetLastHurtingFactor(list, i);
					break;
				}
			}
			return list;
		}

		private static bool InjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Callvirt)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Method(typeof(NewMovement), "GetHurt", new Type[7]
				{
					typeof(int),
					typeof(bool),
					typeof(float),
					typeof(bool),
					typeof(bool),
					typeof(float),
					typeof(bool)
				}, (Type[])null));
			}
			return false;
		}

		private static void SetLastHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Call, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Stfld, AccessTools.Field(typeof(EnemyIdentifierManager), "LastHurtingFactor"))));
		}
	}
	[HarmonyPatch(typeof(Turret))]
	public class TurretPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(Turret), "Shoot")]
		private static IEnumerable<CodeInstruction> Turret_Shoot_Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (InjectionPoint(list[i]))
				{
					RegisterBeamHurtingFactor(list, i + 1);
					break;
				}
			}
			return list;
		}

		private static bool InjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Stfld)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Field(typeof(RevolverBeam), "target"));
			}
			return false;
		}

		private static void RegisterBeamHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldloc_0, null), (OpCodes.Callvirt, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Ldfld, AccessTools.Field(typeof(Turret), "eid")), (OpCodes.Callvirt, AccessTools.Method(typeof(EnemyIdentifierManager), "RegisterFactor", new Type[2]
			{
				typeof(GameObject),
				typeof(EnemyIdentifier)
			}, (Type[])null)), (OpCodes.Nop, null)));
		}
	}
	[HarmonyPatch(typeof(VirtueInsignia))]
	public class VirtueInsigniaPatch
	{
		[HarmonyTranspiler]
		[HarmonyPatch(typeof(VirtueInsignia), "OnTriggerEnter")]
		private static IEnumerable<CodeInstruction> VirtueInsignia_OnTriggerEnter_Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator generator)
		{
			List<CodeInstruction> list = instructions.ToList();
			for (int i = 0; i < list.Count; i++)
			{
				if (InjectionPoint(list[i]))
				{
					SetBeamHurtingFactor(list, i + 1);
					break;
				}
			}
			return list;
		}

		private static bool InjectionPoint(CodeInstruction instruction)
		{
			if (instruction.opcode == OpCodes.Callvirt)
			{
				return CodeInstructionExtensions.OperandIs(instruction, (MemberInfo)AccessTools.Method(typeof(NewMovement), "LaunchFromPoint", new Type[3]
				{
					typeof(Vector3),
					typeof(float),
					typeof(float)
				}, (Type[])null));
			}
			return false;
		}

		private static void SetBeamHurtingFactor(List<CodeInstruction> instructions, int index)
		{
			instructions.InsertRange(index, ReflectionUtils.IL((OpCodes.Call, AccessTools.Method(typeof(EnemyIdentifierManager), "get_Instance", (Type[])null, (Type[])null)), (OpCodes.Ldarg_0, null), (OpCodes.Call, AccessTools.Method(typeof(Component), "get_gameObject", (Type[])null, (Type[])null)), (OpCodes.Stfld, AccessTools.Field(typeof(EnemyIdentifierManager), "LastHurtingFactor"))));
		}
	}
	[HarmonyPatch(typeof(ZombieProjectiles))]
	public class ZombieProjectilesPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(ZombieProjectiles), "ThrowProjectile")]
		public static void ZombieProjectiles_ThrowProjectile_Postfix(GameObject ___currentProjectile, EnemyIdentifier ___eid, ZombieProjectiles __instance)
		{
			Projectile componentInChildren = ___currentProjectile.gameObject.GetComponentInChildren<Projectile>();
			if ((Object)(object)componentInChildren == (Object)null)
			{
				return;
			}
			MonoSingleton<EnemyIdentifierManager>.Instance.RegisterFactor(((Component)componentInChildren).gameObject, ___eid);
			ProjectileSpread val = default(ProjectileSpread);
			if (___currentProjectile.TryGetComponent<ProjectileSpread>(ref val))
			{
				Projectile[] componentsInChildren = ___currentProjectile.GetComponentsInChildren<Projectile>();
				foreach (Projectile val2 in componentsInChildren)
				{
					MonoSingleton<EnemyIdentifierManager>.Instance.RegisterFactor(((Component)val2).gameObject, ___eid);
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ZombieProjectiles), "ShootProjectile")]
		public static void ZombieProjectiles_ShootProjectile_Postfix(GameObject ___currentProjectile, EnemyIdentifier ___eid, ZombieProjectiles __instance)
		{
			if (!((Object)(object)___currentProjectile == (Object)null))
			{
				Projectile val = default(Projectile);
				if (___currentProjectile.TryGetComponent<Projectile>(ref val))
				{
					MonoSingleton<EnemyIdentifierManager>.Instance.RegisterFactor(((Component)val).gameObject, ___eid);
				}
				ProjectileSpread val2 = default(ProjectileSpread);
				if (___currentProjectile.TryGetComponent<ProjectileSpread>(ref val2))
				{
					ProjectileSpread componentInChildren = ((Component)val2).GetComponentInChildren<ProjectileSpread>();
					MonoSingleton<EnemyIdentifierManager>.Instance.RegisterFactor(((Component)componentInChildren).gameObject, ___eid);
				}
			}
		}
	}
	[HarmonyPatch(typeof(ProjectileSpread))]
	public class ProjectileSpreadPatch
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(ProjectileSpread), "Start")]
		private static bool ProjectileSpread_Start_Prefix(ProjectileSpread __instance, ref EnemyIdentifier __state)
		{
			EnemyIdentifier identifierFor = MonoSingleton<EnemyIdentifierManager>.Instance.GetIdentifierFor(((Component)__instance).GetComponentInChildren<Projectile>());
			if ((Object)(object)identifierFor != (Object)null)
			{
				__state = identifierFor;
			}
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(ProjectileSpread), "Start")]
		private static void ProjectileSpread_Start_Postfix(ProjectileSpread __instance, EnemyIdentifier __state)
		{
			if (!((Object)(object)__state == (Object)null))
			{
				Projectile[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Projectile>();
				foreach (Projectile val in componentsInChildren)
				{
					MonoSingleton<EnemyIdentifierManager>.Instance.RegisterFactor(((Component)val).gameObject, __state);
				}
			}
		}
	}
}
namespace UKEnemyIdentifier.Components
{
	[ConfigureSingleton(/*Could not decode attribute arguments.*/)]
	public class EnemyIdentifierManager : MonoSingleton<EnemyIdentifierManager>
	{
		public class PlayerHurtEvent
		{
			public EnemyIdentifier EnemyId;

			public bool PlayerIsKilled;

			public int Damage;
		}

		public delegate void PlayerHurtEventDelegate(PlayerHurtEvent data);

		internal bool DeadAlready;

		internal GameObject LastHurtingFactor;

		private List<(GameObject, EnemyIdentifier)> _killingFactorByOrigin = new List<(GameObject, EnemyIdentifier)>();

		public event PlayerHurtEventDelegate OnPlayerHurt;

		internal void PlayerHurt(EnemyIdentifier eid, int damage, bool playerKilled = false)
		{
			this.OnPlayerHurt?.Invoke(new PlayerHurtEvent
			{
				EnemyId = eid,
				PlayerIsKilled = playerKilled,
				Damage = damage
			});
		}

		private void Start()
		{
			SceneManager.sceneLoaded += delegate
			{
				DeadAlready = false;
			};
			((MonoBehaviour)this).StartCoroutine(SlowUpdate());
		}

		private void Update()
		{
			LastHurtingFactor = null;
		}

		internal void RegisterFactor(GameObject factor, EnemyIdentifier emitter)
		{
			_killingFactorByOrigin.Add((factor, emitter));
		}

		internal void RegisterProjectileSpread(GameObject factor, GameObject projectile)
		{
			(GameObject, EnemyIdentifier) tuple = _killingFactorByOrigin.FirstOrDefault(((GameObject, EnemyIdentifier) e) => (Object)(object)e.Item1 == (Object)(object)projectile);
			var (val, val2) = tuple;
			if ((Object)(object)val != (Object)null || (Object)(object)val2 != (Object)null)
			{
				_killingFactorByOrigin.Add((factor, tuple.Item2));
			}
		}

		internal EnemyIdentifier GetIdentifierFor(Projectile projectile)
		{
			return (from pair in _killingFactorByOrigin
				where (Object)(object)pair.Item1 == (Object)(object)((Component)projectile).gameObject
				select pair.Item2).FirstOrDefault();
		}

		internal EnemyIdentifier GetIdentifierFor(RevolverBeam beam)
		{
			return (from pair in _killingFactorByOrigin
				where (Object)(object)pair.Item1 == (Object)(object)((Component)beam).gameObject
				select pair.Item2).FirstOrDefault();
		}

		internal EnemyIdentifier GetIdentifierFor(LightningStrikeExplosive beam)
		{
			return (from pair in _killingFactorByOrigin
				where (Object)(object)pair.Item1 == (Object)(object)((Component)beam).gameObject
				select pair.Item2).FirstOrDefault();
		}

		internal void RegisterRevolverBeamExplosion(RevolverBeam beam, Explosion explosion)
		{
			EnemyIdentifier identifierFor = GetIdentifierFor(beam);
			if (!((Object)(object)identifierFor == (Object)null))
			{
				explosion.originEnemy = identifierFor;
			}
		}

		internal void RegisterLightningStrikeExplosion(LightningStrikeExplosive lightning, Explosion explosion)
		{
			EnemyIdentifier identifierFor = GetIdentifierFor(lightning);
			if (!((Object)(object)identifierFor == (Object)null))
			{
				explosion.originEnemy = identifierFor;
			}
		}

		internal EnemyIdentifier IdentifyEnemy()
		{
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Invalid comparison between Unknown and I4
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Expected O, but got Unknown
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)LastHurtingFactor == (Object)null)
			{
				return null;
			}
			Projectile val = default(Projectile);
			PhysicalShockwave val2 = default(PhysicalShockwave);
			MassSpear val3 = default(MassSpear);
			RevolverBeam val4 = default(RevolverBeam);
			ContinuousBeam val5 = default(ContinuousBeam);
			if (LastHurtingFactor.TryGetComponent<Projectile>(ref val) || LastHurtingFactor.TryGetComponent<PhysicalShockwave>(ref val2) || LastHurtingFactor.TryGetComponent<MassSpear>(ref val3) || LastHurtingFactor.TryGetComponent<RevolverBeam>(ref val4) || LastHurtingFactor.TryGetComponent<ContinuousBeam>(ref val5))
			{
				return FindByHurtingFactor(LastHurtingFactor);
			}
			SwingCheck2 val6 = default(SwingCheck2);
			if (LastHurtingFactor.TryGetComponent<SwingCheck2>(ref val6))
			{
				return val6.eid;
			}
			Explosion val7 = default(Explosion);
			if (LastHurtingFactor.TryGetComponent<Explosion>(ref val7))
			{
				return val7.originEnemy;
			}
			FireZone val8 = default(FireZone);
			if (LastHurtingFactor.TryGetComponent<FireZone>(ref val8))
			{
				if ((int)val8.source != 1)
				{
					return null;
				}
				return ((Streetcleaner)ReflectionUtils.GetPrivate<FireZone>(val8, typeof(FireZone), "sc")).eid;
			}
			VirtueInsignia val9 = default(VirtueInsignia);
			if (LastHurtingFactor.TryGetComponent<VirtueInsignia>(ref val9))
			{
				return (EnemyIdentifier)ReflectionUtils.GetPrivate<Drone>(val9.parentDrone, typeof(Drone), "eid");
			}
			return null;
		}

		private EnemyIdentifier FindByHurtingFactor(GameObject go)
		{
			return (from pair in _killingFactorByOrigin
				where (Object)(object)pair.Item1 == (Object)(object)go
				select pair.Item2).FirstOrDefault();
		}

		private IEnumerator SlowUpdate()
		{
			while (true)
			{
				UpdateList();
				yield return (object)new WaitForSecondsRealtime(1f);
			}
		}

		private void UpdateList()
		{
			_killingFactorByOrigin = _killingFactorByOrigin.Where(((GameObject, EnemyIdentifier) e) => (Object)(object)e.Item1 != (Object)null && (Object)(object)e.Item2 != (Object)null).ToList();
		}
	}
}