Decompiled source of Hydra v0.0.0

Hydra.dll

Decompiled 3 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Nyxpiri.Collections.Generic;
using Nyxpiri.ULTRAKILL.NyxLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.0.0.0")]
namespace Nyxpiri.ULTRAKILL.Hydra;

internal static class Log
{
	private static ManualLogSource _logger;

	public static void Initialize(ManualLogSource logger)
	{
		Assert.IsNull((object)_logger, "Log.Initialize called when _logger wasn't null?");
		_logger = logger;
	}

	public static void Fatal(object data)
	{
		_logger.LogFatal(data);
	}

	public static void Error(object data)
	{
		_logger.LogError(data);
	}

	public static void Warning(object data)
	{
		_logger.LogWarning(data);
	}

	public static void Message(object data)
	{
		_logger.LogMessage(data);
	}

	public static void Info(object data)
	{
		_logger.LogInfo(data);
	}

	public static void Debug(object data)
	{
		if (Options.LogDebugInfo.Value)
		{
			_logger.LogDebug(data);
		}
	}
}
public static class HydraDupeQueue
{
	public struct QueuedDupeInfo
	{
		public Vector3 Position;

		public Quaternion Rotation;

		public Vector3 LocalScale;

		public EnemyHydra.SharedData SharedData;

		public EnemyCloneStore CloneStore;

		public int Depth;

		public EnemyType EnemyType;

		public Transform CloneParent;

		public bool BossBar;
	}

	public static int InstantiatedThisTick = 0;

	public static ulong NumFixedUpdates = 0uL;

	private static Queue<QueuedDupeInfo> DupeQueue = new Queue<QueuedDupeInfo>(256);

	private static Stack<QueuedDupeInfo> ImmediatelyDupeStack = new Stack<QueuedDupeInfo>(256);

	public static void Initialize()
	{
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a5: Expected O, but got Unknown
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b7: Expected O, but got Unknown
		EnemyEvents.PreDeath = (Action<EnemyComponents, bool>)Delegate.Combine(EnemyEvents.PreDeath, new Action<EnemyComponents, bool>(PreEnemyDeath));
		EnemyEvents.PreDeath = (Action<EnemyComponents, bool>)Delegate.Combine(EnemyEvents.PreDeath, (Action<EnemyComponents, bool>)delegate(EnemyComponents eid, bool instakill)
		{
			GameObject gameObject = ((Component)eid).gameObject;
			EnemyComponents component = gameObject.GetComponent<EnemyComponents>();
			EnemyHydra hydraComp = component.GetHydraComp();
			hydraComp.NotifyOfDeath(instakill);
		});
		EnemyEvents.Death = (Action<EnemyComponents>)Delegate.Combine(EnemyEvents.Death, new Action<EnemyComponents>(DuringEnemyDeath));
		EnemyEvents.PostDeath = (Action<EnemyComponents, bool>)Delegate.Combine(EnemyEvents.PostDeath, new Action<EnemyComponents, bool>(PostEnemyDeath));
		UpdateEvents.OnLateUpdate += new OnLateUpdateEventHandler(LateUpdate);
		UpdateEvents.OnFixedUpdate += new OnFixedUpdateEventHandler(FixedUpdate);
	}

	private static void FixedUpdate()
	{
		if (Cheats.IsCheatDisabled("nyxpiri.hydra-mode"))
		{
			return;
		}
		for (int i = InstantiatedThisTick; i < Options.HydraMaxPerUpdate.Value; i++)
		{
			if (DupeQueue.Count == 0)
			{
				break;
			}
			QueuedDupeInfo dupeInfo = DupeQueue.Dequeue();
			InstantiateDupe(dupeInfo);
		}
		InstantiatedThisTick = 0;
		NumFixedUpdates++;
	}

	public static void EnqueueDupe(QueuedDupeInfo dupeInfo)
	{
		if (InstantiatedThisTick >= Options.HydraMaxPerUpdate.Value)
		{
			DupeQueue.Enqueue(dupeInfo);
		}
		else
		{
			ImmediatelyDupeStack.Push(dupeInfo);
		}
	}

	private static void PreEnemyDeath(EnemyComponents enemy, bool instakill)
	{
		GameObject gameObject = ((Component)enemy).gameObject;
		EnemyHydra hydraComp = enemy.GetHydraComp();
		hydraComp.NotifyOfDeath(instakill);
	}

	private static void PostEnemyDeath(EnemyComponents enemy, bool instakill)
	{
	}

	private static void DuringEnemyDeath(EnemyComponents enemy)
	{
		GameObject gameObject = ((Component)enemy).gameObject;
		EnemyHydra hydraComp = enemy.GetHydraComp();
		hydraComp.NotifyOfDeath(instakill: false);
		hydraComp.DuringDeath();
	}

	private static void LateUpdate()
	{
		if (!Cheats.IsCheatDisabled("nyxpiri.hydra-mode"))
		{
			while (ImmediatelyDupeStack.Count > 0)
			{
				InstantiateDupe(ImmediatelyDupeStack.Pop());
			}
		}
	}

	public static void InstantiateDupe(QueuedDupeInfo dupeInfo)
	{
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Invalid comparison between Unknown and I4
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b2: 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)
		InstantiatedThisTick++;
		GameObject val = dupeInfo.CloneStore.GetNewInstance(dupeInfo.CloneParent);
		GameObject val2 = null;
		EnemyComponents val3;
		if ((int)dupeInfo.EnemyType == 4)
		{
			val2 = val;
			val3 = val.GetComponentInChildren<EnemyComponents>();
			Assert.IsNotNull((Object)(object)val3, "");
			val = ((Component)val3).gameObject;
		}
		else
		{
			Assert.IsNotNull((Object)(object)val, "");
			val3 = val.GetComponent<EnemyComponents>();
		}
		val.transform.position = dupeInfo.Position;
		val.transform.rotation = dupeInfo.Rotation;
		val.SetActive(true);
		if (val2 != null)
		{
			val2.SetActive(true);
		}
		EnemyIdentifier component = val.GetComponent<EnemyIdentifier>();
		component.spawnIn = false;
		component.timeSinceSpawned = TimeSince.op_Implicit(0f);
		Assert.IsNotNull((Object)(object)val3, "");
		Assert.IsNotNull((Object)(object)val3.GetHydraComp(), "");
		Assert.IsNotNull((Object)(object)val3.GetHydraComp().Shared, "");
		val3.GetHydraComp().Depth = dupeInfo.Depth;
		if (dupeInfo.BossBar)
		{
			component.BossBar(true);
		}
		dupeInfo.CloneStore.RemoveReservation();
	}
}
public static class EnemyHydraEnemyComponentsExtension
{
	public static EnemyHydra GetHydraComp(this EnemyComponents enemy)
	{
		return enemy.GetMonoByIndex<EnemyHydra>(EnemyHydra.MonoRegistrarIdx);
	}
}
public class EnemyHydra : MonoBehaviour
{
	public class SharedData : ScriptableObject
	{
		private ReserveList<GameObject> Instances = new ReserveList<GameObject>(16);

		public bool CountAsKill = false;

		public Bounds Bounds = default(Bounds);

		public Action OnDeactivated = null;

		internal string CreatorName = "";

		public ScriptableObject EnemySpecificShared = null;

		private static int SharedIDIncrementer;

		public int InstanceCount => Instances.Count;

		public int GlobalIdx { get; private set; } = -1;

		public bool Active { get; private set; } = false;

		protected SharedData()
		{
		}//IL_001a: Unknown result type (might be due to invalid IL or missing references)


		internal void UnregisterInstance(int sharedIdx)
		{
			Instances.RemoveAt(sharedIdx);
			if (InstanceCount == 0)
			{
				Deactivate();
			}
		}

		internal int RegisterInstance(GameObject gameObject)
		{
			int result = Instances.Add(gameObject);
			if (!Active)
			{
				Activate();
			}
			return result;
		}

		private void Deactivate()
		{
			Assert.IsTrue(Active, "");
			Log.Debug("EnemyHydraMod.SharedData '" + ((Object)this).name + "' with creator '" + CreatorName + "' deactivated!");
			OnDeactivated?.Invoke();
			Active = false;
		}

		private void Activate()
		{
			Assert.IsFalse(Active, "");
			Log.Debug("EnemyHydraMod.SharedData '" + ((Object)this).name + "' with creator '" + CreatorName + "' activated!");
			Active = true;
		}

		private void Awake()
		{
			((Object)this).name = ((Object)this).name + SharedIDIncrementer;
			SharedIDIncrementer++;
			Log.Debug("EnemyHydraMod.SharedData '" + ((Object)this).name + "' with creator '" + CreatorName + "' awakened!");
		}

		private void OnDestroy()
		{
			Log.Debug("EnemyHydraMod.SharedData '" + ((Object)this).name + "' with creator '" + CreatorName + "' destroyed!");
			if (Active)
			{
				Deactivate();
			}
		}
	}

	public SharedData Shared = null;

	public int Depth = -1;

	[NonSerialized]
	public EnemyIdentifier Eid = null;

	[NonSerialized]
	public EnemyComponents Enemy = null;

	public EnemyGameplayRank GameplayRank = (EnemyGameplayRank)3;

	[NonSerialized]
	public bool ContributesToInstanceCount = false;

	[NonSerialized]
	public Action PreDeath = null;

	private bool _excludedFromHydraCheat = false;

	private float NoDupeTime = 0f;

	private bool NotifiedOfDeathCalled = false;

	private static FieldAccess<TimeController, GameObject> parryLightFA = new FieldAccess<TimeController, GameObject>("parryLight", BindingFlags.Instance | BindingFlags.NonPublic);

	public bool CanDuplicate => Shared.InstanceCount < Options.HydraMaxFromOne.Value && (NoDupeTime < 0f || Depth == 0);

	public bool HydraKilled { get; private set; } = false;

	public bool HydraDuped { get; private set; } = false;

	public int SharedIdx { get; private set; } = -1;

	public string SharedName { get; private set; } = null;

	public static int MonoRegistrarIdx { get; private set; }

	public bool ExcludedFromHydraCheat
	{
		get
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Invalid comparison between Unknown and I4
			int result;
			if (!_excludedFromHydraCheat)
			{
				if (Eid?.puppet ?? false)
				{
					EnemyIdentifier eid = Eid;
					result = ((eid == null || (int)eid.enemyType != 36) ? 1 : 0);
				}
				else
				{
					result = 0;
				}
			}
			else
			{
				result = 1;
			}
			return (byte)result != 0;
		}
	}

	protected void OnDestroy()
	{
		TryUnregisterWithShared();
	}

	protected void OnEnable()
	{
		if (SharedName != null)
		{
			TryRegisterWithShared();
		}
	}

	protected void OnDisable()
	{
		if (SharedName != null)
		{
			TryUnregisterWithShared();
		}
	}

	private void TryUnregisterWithShared()
	{
		if (ExcludedFromHydraCheat)
		{
			return;
		}
		Assert.IsNotNull((Object)(object)Shared, "Shared was null! Shared Name: '" + SharedName + "'");
		if (ContributesToInstanceCount)
		{
			Log.Debug(((Object)this).name + ": unregistered with shared!");
			if (!Eid.dead)
			{
				PreDeath?.Invoke();
			}
			Shared.UnregisterInstance(SharedIdx);
			SharedIdx = -1;
			ContributesToInstanceCount = false;
			if (Depth != 0)
			{
			}
			MusicManager instance = MonoSingleton<MusicManager>.Instance;
			if (instance != null)
			{
				instance.PlayCleanMusic();
			}
		}
	}

	protected void Update()
	{
		if (!Cheats.IsCheatDisabled("nyxpiri.hydra-mode") && !ExcludedFromHydraCheat && !Eid.Dead && NoDupeTime >= 0f)
		{
			NoDupeTime -= Time.deltaTime / Mathf.Max(1f, (float)Shared.InstanceCount * 0.3f + 0.667f);
			if (NoDupeTime <= 0f)
			{
				NoDupeTime = -1f;
			}
		}
	}

	protected void Awake()
	{
		Eid = ((Component)this).GetComponent<EnemyIdentifier>();
		Enemy = ((Component)this).GetComponent<EnemyComponents>();
		if ((Object)(object)Shared == (Object)null)
		{
			InitializeAsNew();
		}
	}

	protected void Start()
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Invalid comparison between Unknown and I4
		//IL_0016: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Invalid comparison between Unknown and I4
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Invalid comparison between Unknown and I4
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Invalid comparison between Unknown and I4
		//IL_016c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0171: Unknown result type (might be due to invalid IL or missing references)
		//IL_017c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0183: Invalid comparison between Unknown and I4
		//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Invalid comparison between Unknown and I4
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0208: Expected I4, but got Unknown
		//IL_02bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c3: Invalid comparison between Unknown and I4
		//IL_0394: Unknown result type (might be due to invalid IL or missing references)
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_039b: Unknown result type (might be due to invalid IL or missing references)
		//IL_039d: Unknown result type (might be due to invalid IL or missing references)
		//IL_039f: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a2: Invalid comparison between Unknown and I4
		//IL_03a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_03aa: Invalid comparison between Unknown and I4
		if ((int)Eid.enemyType == 39 || (int)Eid.enemyType == 21 || ((int)Eid.enemyType == 35 && ((Object)((Component)Eid).gameObject).name.Contains("rain", StringComparison.OrdinalIgnoreCase)) || (int)Eid.enemyType == 22 || Enemy.UniquelySolo)
		{
			_excludedFromHydraCheat = true;
			return;
		}
		Assert.IsNotNull((Object)(object)Eid, "For object by name " + ((Object)((Component)this).gameObject).name);
		if (Eid.dead)
		{
			return;
		}
		Assert.IsTrue(Depth >= 0, "For object by name " + ((Object)((Component)this).gameObject).name);
		Assert.IsNotNull((Object)(object)Shared, "For object by name " + ((Object)((Component)this).gameObject).name + " shared was null! Shared Name: '" + SharedName + "'");
		MusicManager instance = MonoSingleton<MusicManager>.Instance;
		if (instance != null)
		{
			instance.PlayBattleMusic();
		}
		if (Depth > 0)
		{
			Eid.dontCountAsKills = true;
		}
		else
		{
			Shared.CountAsKill = !Eid.dontCountAsKills;
		}
		GameplayRank = EnemyUtils.GetEnemyGameplayRank(Eid);
		if ((int)Eid.enemyType == 38)
		{
			NoDupeTime = Options.HydraBossWaitTime.Value;
		}
		else if ((int)Eid.enemyType == 41)
		{
			NoDupeTime = (Eid.isBoss ? Options.HydraUltraBossWaitTime.Value : Options.HydraBossWaitTime.Value);
		}
		else
		{
			EnemyGameplayRank gameplayRank = GameplayRank;
			EnemyGameplayRank val = gameplayRank;
			switch ((int)val)
			{
			case 0:
				NoDupeTime = Options.HydraDefaultWaitTime.Value;
				break;
			case 1:
				NoDupeTime = Options.HydraMiniBossWaitTime.Value;
				break;
			case 2:
				NoDupeTime = Options.HydraBossWaitTime.Value;
				break;
			case 3:
				NoDupeTime = Options.HydraUltraBossWaitTime.Value;
				break;
			}
		}
		if (Cheats.Enabled)
		{
			float num = Enemy.Health;
			for (int i = 0; i < Depth; i++)
			{
				num *= Options.HydraHealthDecayScale.Value;
			}
			Enemy.Health = num;
		}
		if (Depth > 0)
		{
			if ((int)Eid.enemyType == 4)
			{
				((Component)((Component)this).gameObject.transform.parent).gameObject.AddComponent<DestroyOnCheckpointRestart>();
			}
			else
			{
				((Component)this).gameObject.AddComponent<DestroyOnCheckpointRestart>();
			}
		}
		DroneFlesh component = ((Component)Eid).GetComponent<DroneFlesh>();
		if (Depth > 0 && (Object)(object)component != (Object)null)
		{
			Light component2 = ((Component)this).GetComponent<Light>();
			if ((Object)(object)component2 != (Object)null)
			{
				((Behaviour)component2).enabled = false;
			}
			Light[] componentsInChildren = ((Component)this).GetComponentsInChildren<Light>();
			Light[] array = componentsInChildren;
			foreach (Light val2 in array)
			{
				((Behaviour)val2).enabled = false;
			}
		}
		if ((Object)(object)component != (Object)null)
		{
			((Component)this).gameObject.AddComponent<FleshDroneHydra>();
		}
		EnemyType enemyType = Eid.enemyType;
		EnemyType val3 = enemyType;
		if ((int)val3 != 1 && (int)val3 == 30)
		{
			((Component)this).gameObject.AddComponent<FleshPanopticonHydra>();
		}
		TryRegisterWithShared();
	}

	private void TryRegisterWithShared()
	{
		Assert.IsNotNull((Object)(object)Shared, "Shared was null! Shared Name: '" + SharedName + "'");
		if (!ContributesToInstanceCount)
		{
			Log.Debug(((Object)this).name + ": registered with shared!");
			SharedIdx = Shared.RegisterInstance(((Component)this).gameObject);
			ContributesToInstanceCount = true;
		}
	}

	public void NotifyOfDeath(bool instakill)
	{
		//IL_0358: Unknown result type (might be due to invalid IL or missing references)
		//IL_035f: Invalid comparison between Unknown and I4
		//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
		//IL_023b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0240: Unknown result type (might be due to invalid IL or missing references)
		//IL_0242: Unknown result type (might be due to invalid IL or missing references)
		//IL_0244: Unknown result type (might be due to invalid IL or missing references)
		//IL_0246: Unknown result type (might be due to invalid IL or missing references)
		//IL_025d: Expected I4, but got Unknown
		if (NotifiedOfDeathCalled)
		{
			return;
		}
		Log.Debug($"{((Object)this).name}: EnemyHydraMod::NotifyOfDeath called with instakill as {instakill}");
		NotifiedOfDeathCalled = true;
		if (ExcludedFromHydraCheat)
		{
			return;
		}
		if ((Object)(object)Eid == (Object)null)
		{
			Eid = ((Component)this).GetComponent<EnemyIdentifier>();
		}
		if (!ContributesToInstanceCount || !Cheats.IsCheatEnabled("nyxpiri.hydra-mode"))
		{
			return;
		}
		Eid.dontCountAsKills = true;
		PreDeath?.Invoke();
		if (Depth != 0 || !Shared.CountAsKill || !Cybergrind.IsActive)
		{
		}
		if (!instakill)
		{
			TryEnqueueDupe(isB: false);
			TryEnqueueDupe(isB: true);
		}
		TryUnregisterWithShared();
		if (!HydraDuped && Shared.InstanceCount == 0)
		{
			Log.Debug($"{((Object)this).name}: EnemyHydraMod::NotifyOfDeath called and we were hydrakilled, {Shared.InstanceCount} remaining instances, HydraDuped: {HydraDuped}");
			HydraKilled = true;
			if (Shared.CountAsKill)
			{
				StatsManager instance = MonoSingleton<StatsManager>.Instance;
				instance.kills++;
				ContributeToActivateNextWave();
				Enemy.Enemy.gz.EnemyDeath(Eid);
				if (Shared.CountAsKill && !Cybergrind.IsActive)
				{
				}
			}
			GameObject val = Object.Instantiate<GameObject>(parryLightFA.GetValue(MonoSingleton<TimeController>.Instance), MonoSingleton<PlayerTracker>.Instance.GetTarget().position, Quaternion.identity, MonoSingleton<PlayerTracker>.Instance.GetTarget());
			Light val2 = default(Light);
			if (val.TryGetComponent<Light>(ref val2))
			{
				((Behaviour)val2).enabled = false;
			}
			AudioSource componentInChildren = val.GetComponentInChildren<AudioSource>();
			componentInChildren.volume *= Options.HydraKillSoundVolume.Value;
			Log.Debug(((Object)this).name + ": About to try give points for hydra kill...");
			EnemyGameplayRank gameplayRank = GameplayRank;
			EnemyGameplayRank val3 = gameplayRank;
			switch ((int)val3)
			{
			case 0:
				MonoSingleton<StyleHUD>.Instance.AddPoints(10, "<color=#a2beff>HYDRA KILL</color>", (GameObject)null, Eid, -1, "", "");
				break;
			case 1:
				MonoSingleton<StyleHUD>.Instance.AddPoints(50, "<color=#8d96fe>KINDA BIG HYDRA KILL</color>", (GameObject)null, Eid, -1, "", "");
				break;
			case 2:
				MonoSingleton<StyleHUD>.Instance.AddPoints(100, "<color=#8a2af7>BIG HYDRA KILL</color>", (GameObject)null, Eid, -1, "", "");
				break;
			case 3:
				MonoSingleton<StyleHUD>.Instance.AddPoints(0, "<color=#ffdb00>HOW??</color>", (GameObject)null, Eid, -1, "", "");
				MonoSingleton<StyleHUD>.Instance.AddPoints(1000, "<color=#ffdb00>ULTRA HYDRA KILL</color>", (GameObject)null, Eid, -1, "", "");
				break;
			default:
				throw new InvalidOperationException();
			}
			Log.Debug(((Object)this).name + ": Points should have been given for hydra kill");
		}
		else
		{
			Eid.puppet = !instakill;
			if ((int)Eid.enemyType == 38)
			{
				Eid.drone.spawnOnDeath = null;
				Eid.drone.cantInstaExplode = true;
			}
			Log.Debug($"{((Object)this).name}: EnemyHydraMod::NotifyOfDeath called and we were NOT hydrakilled, {Shared.InstanceCount} remaining instances, HydraDuped: {HydraDuped}");
		}
	}

	private void ContributeToActivateNextWave()
	{
		ActivateNextWave activateNextWave = Enemy.Cloning.ActivateNextWave;
		if (activateNextWave != null)
		{
			activateNextWave.AddDeadEnemy();
		}
	}

	private void TryEnqueueDupe(bool isB)
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Invalid comparison between Unknown and I4
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//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_009d: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_0146: Unknown result type (might be due to invalid IL or missing references)
		//IL_014d: Invalid comparison between Unknown and I4
		//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b4: Invalid comparison between Unknown and I4
		//IL_015e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0164: Unknown result type (might be due to invalid IL or missing references)
		//IL_0169: Unknown result type (might be due to invalid IL or missing references)
		//IL_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d1: Invalid comparison between Unknown and I4
		//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b9: Invalid comparison between Unknown and I4
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d9: Invalid comparison between Unknown and I4
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Invalid comparison between Unknown and I4
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_0247: Unknown result type (might be due to invalid IL or missing references)
		//IL_024d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0252: Unknown result type (might be due to invalid IL or missing references)
		//IL_0257: Unknown result type (might be due to invalid IL or missing references)
		//IL_025c: Unknown result type (might be due to invalid IL or missing references)
		//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e1: Invalid comparison between Unknown and I4
		//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c9: Invalid comparison between Unknown and I4
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_027a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0281: Unknown result type (might be due to invalid IL or missing references)
		//IL_0286: Unknown result type (might be due to invalid IL or missing references)
		//IL_028b: Unknown result type (might be due to invalid IL or missing references)
		if (ExcludedFromHydraCheat || !CanDuplicate)
		{
			return;
		}
		Log.Debug(((Object)this).name + ": Now HydraDuped by TryEnqueueDupe");
		HydraDuped = true;
		HydraDupeQueue.QueuedDupeInfo dupeInfo = default(HydraDupeQueue.QueuedDupeInfo);
		if ((int)Eid.enemyType == 1)
		{
			dupeInfo.Position = ((Component)((Component)Eid.drone).GetComponent<Rigidbody>()).transform.position;
		}
		else
		{
			dupeInfo.Position = ((Component)this).transform.position;
		}
		dupeInfo.Rotation = ((Component)this).transform.rotation;
		dupeInfo.LocalScale = ((Component)this).transform.localScale;
		dupeInfo.SharedData = Shared;
		dupeInfo.Depth = Depth + 1;
		dupeInfo.EnemyType = Eid.enemyType;
		dupeInfo.BossBar = (Object)(object)((Component)this).GetComponent<BossHealthBar>() != (Object)null;
		dupeInfo.CloneStore = Enemy.Cloning.Store;
		dupeInfo.CloneStore.AddReservation();
		ActivateNextWave activateNextWave = Enemy.Cloning.ActivateNextWave;
		dupeInfo.CloneParent = ((activateNextWave != null) ? ((Component)activateNextWave).transform : null);
		if ((int)Eid.enemyType == 19)
		{
			ref Vector3 position = ref dupeInfo.Position;
			position += dupeInfo.Rotation * Vector3.right * (isB ? (-4.25f) : 4.25f);
			goto IL_0291;
		}
		float num = 1f;
		EnemyType enemyType = Eid.enemyType;
		EnemyType val = enemyType;
		if ((int)val <= 17)
		{
			if ((int)val != 2)
			{
				if ((int)val != 11)
				{
					if ((int)val == 17)
					{
						goto IL_01f7;
					}
				}
				else
				{
					num = 0f;
				}
			}
			else
			{
				num = 0f;
			}
		}
		else if ((int)val != 23)
		{
			if ((int)val != 24)
			{
				if ((int)val == 30)
				{
					goto IL_01f7;
				}
			}
			else
			{
				num = 0f;
			}
		}
		else
		{
			num = 0f;
		}
		goto IL_0214;
		IL_01f7:
		num = 0f;
		goto IL_0214;
		IL_0291:
		HydraDupeQueue.EnqueueDupe(dupeInfo);
		return;
		IL_0214:
		if ((Object)(object)((Component)this).GetComponent<CancerousRodent>() != (Object)null)
		{
			num = 0.01f;
		}
		ref Vector3 position2 = ref dupeInfo.Position;
		position2 += Vector3.Project(((Bounds)(ref dupeInfo.SharedData.Bounds)).size, dupeInfo.Rotation * Vector3.right) * (isB ? (-1f) : 1f) * 0.3f * num;
		goto IL_0291;
	}

	private void InitializeAsNew()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_0051: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: 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)
		//IL_005c: Invalid comparison between Unknown and I4
		Shared = ScriptableObject.CreateInstance<SharedData>();
		TryRegisterWithShared();
		Shared.Bounds = EnemyUtils.SolveEnemyBounds(((Component)this).gameObject);
		if ((Object)(object)((Component)this).GetComponent<DroneFlesh>() != (Object)null)
		{
			Shared.EnemySpecificShared = (ScriptableObject)(object)new FleshDroneHydra.SharedData();
		}
		EnemyType enemyType = Eid.enemyType;
		EnemyType val = enemyType;
		if ((int)val == 30)
		{
			Shared.EnemySpecificShared = (ScriptableObject)(object)new FleshPanopticonHydra.SharedData();
		}
		Depth = 0;
		Shared.CreatorName = ((Object)((Component)this).gameObject).name;
		SharedName = ((Object)Shared).name;
	}

	internal void DuringDeath()
	{
		TryUnregisterWithShared();
	}

	internal static void Initialize()
	{
		MonoRegistrarIdx = EnemyComponents.MonoRegistrar.Register<EnemyHydra>();
	}
}
public static class Cheats
{
	public const string HydraMode = "nyxpiri.hydra-mode";
}
[BepInPlugin("nyxpiri.ultrakill.hydra", "Hydra", "0.0.0")]
[BepInProcess("ULTRAKILL.exe")]
public class Hydra : BaseUnityPlugin
{
	protected void Awake()
	{
		//IL_0014: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Expected O, but got Unknown
		Log.Initialize(((BaseUnityPlugin)this).Logger);
		Cheats.ReadyForCheatRegistration += new ReadyForCheatRegistrationEventHandler(RegisterCheats);
		HydraDupeQueue.Initialize();
		EnemyHydra.Initialize();
		Options.Config = ((BaseUnityPlugin)this).Config;
		Options.Initialize();
		Harmony.CreateAndPatchAll(((object)this).GetType().Assembly, (string)null);
		if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath))
		{
			((BaseUnityPlugin)this).Config.Save();
		}
	}

	protected void Start()
	{
		LevelModder.RegisterLevelMod<P2Additions>("Level P-2");
	}

	protected void Update()
	{
	}

	protected void LateUpdate()
	{
	}

	protected void OnApplicationFocus(bool hasFocus)
	{
		if (hasFocus)
		{
			((BaseUnityPlugin)this).Config.Reload();
		}
	}

	private void RegisterCheats(CheatsManager cheatsManager)
	{
		//IL_004a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Expected O, but got Unknown
		cheatsManager.RegisterCheat((ICheat)new ToggleCheat("Hydra Mode", "nyxpiri.hydra-mode", (Action<ToggleCheat>)delegate
		{
		}, (Action<ToggleCheat, CheatsManager>)delegate
		{
			EnemyCloneManager.RequestInstanceStoreCapacity(5);
		}), "MITOSIS");
		if (Cheats.IsCheatEnabled("nyxpiri.hydra-mode"))
		{
			EnemyCloneManager.RequestInstanceStoreCapacity(5);
		}
	}
}
[HarmonyPatch(typeof(SisyphusPrimeIntro), "OnCollisionEnter")]
internal static class SisyphusPrimeIntroOnCollisionEnterPatch
{
	public static void Prefix(SisyphusPrimeIntro __instance, Collider col)
	{
	}

	public static void Postfix(SisyphusPrimeIntro __instance, Collider col)
	{
		FieldPublisher<SisyphusPrimeIntro, bool> val = new FieldPublisher<SisyphusPrimeIntro, bool>(__instance, "hasHitGround");
		if (val.Value && Cheats.IsCheatEnabled("nyxpiri.hydra-mode"))
		{
			((Component)__instance).gameObject.GetComponent<Collider>().enabled = false;
			((Component)__instance).GetComponent<Rigidbody>().detectCollisions = false;
			Rigidbody[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<Rigidbody>();
			Collider[] componentsInChildren2 = ((Component)__instance).GetComponentsInChildren<Collider>();
			Collider[] array = componentsInChildren2;
			foreach (Collider val2 in array)
			{
				val2.enabled = false;
			}
			Rigidbody[] array2 = componentsInChildren;
			foreach (Rigidbody val3 in array2)
			{
				val3.detectCollisions = false;
			}
		}
	}
}
public class P2Additions : LevelMod
{
	private int NumVirtues = 0;

	private int NumMindflayers = 0;

	private int NumHideousMasses = 0;

	private bool IsBattleWithClean = false;

	private GameObject PanopticonRadio = null;

	private long createPanopticonRadioQueued = 0L;

	public override void OnSceneLoad()
	{
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_007d: Expected O, but got Unknown
		Log.Debug("Level Additions for P-2 OnSceneLoad called!");
		EnemyEvents.PostStart = (Action<EnemyComponents>)Delegate.Combine(EnemyEvents.PostStart, new Action<EnemyComponents>(OnEnemySpawned));
		EnemyEvents.Death = (Action<EnemyComponents>)Delegate.Combine(EnemyEvents.Death, new Action<EnemyComponents>(OnEnemyDie));
		EnemyEvents.PreDestroy = (Action<EnemyComponents>)Delegate.Combine(EnemyEvents.PreDestroy, new Action<EnemyComponents>(OnEnemyDestroy));
		UpdateEvents.OnUpdate += new OnUpdateEventHandler(Update);
	}

	private void Update()
	{
		createPanopticonRadioQueued--;
		if (createPanopticonRadioQueued != 1 || !((Object)(object)PanopticonRadio == (Object)null))
		{
			return;
		}
		createPanopticonRadioQueued = 0L;
		GameObject val = GameObject.Find("BossMusics");
		AudioSource[] componentsInChildren = val.GetComponentsInChildren<AudioSource>();
		AudioSource[] array = componentsInChildren;
		foreach (AudioSource val2 in array)
		{
			if (!((Object)(object)val2.clip == (Object)null) && ((Object)val2.clip).name.Contains("panopticon"))
			{
				PanopticonRadio = Object.Instantiate<GameObject>(((Component)val2).gameObject);
				PanopticonRadio.SetActive(false);
				val2.maxDistance = 400f;
			}
		}
	}

	public override void OnSceneUnload()
	{
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Expected O, but got Unknown
		EnemyEvents.PostStart = (Action<EnemyComponents>)Delegate.Remove(EnemyEvents.PostStart, new Action<EnemyComponents>(OnEnemySpawned));
		EnemyEvents.Death = (Action<EnemyComponents>)Delegate.Remove(EnemyEvents.Death, new Action<EnemyComponents>(OnEnemyDie));
		EnemyEvents.PreDestroy = (Action<EnemyComponents>)Delegate.Remove(EnemyEvents.PreDestroy, new Action<EnemyComponents>(OnEnemyDestroy));
		UpdateEvents.OnUpdate -= new OnUpdateEventHandler(Update);
		DisableBattleWithClean();
	}

	private void OnEnemySpawned(EnemyComponents enemy)
	{
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		//IL_005a: Invalid comparison between Unknown and I4
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Invalid comparison between Unknown and I4
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: Invalid comparison between Unknown and I4
		//IL_0064: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Invalid comparison between Unknown and I4
		Assert.IsTrue(((Component)enemy).gameObject.activeInHierarchy, "");
		if (enemy.Eid.Dead || !((Behaviour)enemy).enabled || !((Behaviour)enemy).isActiveAndEnabled)
		{
			return;
		}
		EnemyType enemyType = enemy.Eid.enemyType;
		EnemyType val = enemyType;
		if ((int)val != 2)
		{
			if ((int)val != 5)
			{
				if ((int)val == 9)
				{
					Log.Debug("P2Additions Detected a Virtue spawn!");
					NumVirtues++;
				}
			}
			else
			{
				Log.Debug("P2Additions Detected a Mindflayer spawn!");
				NumMindflayers++;
			}
		}
		else
		{
			Log.Debug("P2Additions Detected a HideousMass spawn!");
			NumHideousMasses++;
		}
		if (Cheats.IsCheatEnabled("nyxpiri.hydra-mode"))
		{
			if (NumMindflayers >= 2 && NumVirtues >= 2)
			{
				EnableBattleWithClean();
			}
			else if (NumVirtues >= 3 && NumHideousMasses >= 1)
			{
				EnableBattleWithClean();
			}
		}
		else
		{
			DisableBattleWithClean();
		}
		if ((int)enemy.Eid.enemyType == 30 && Cheats.IsCheatEnabled("nyxpiri.hydra-mode"))
		{
			createPanopticonRadioQueued = (((Object)(object)PanopticonRadio == (Object)null) ? 20 : (-1));
		}
	}

	private void EnableBattleWithClean()
	{
		if (!IsBattleWithClean)
		{
			Log.Debug($"Level Additions for P-2 trying to play battle music with clean!\nNumVirtues: {NumVirtues}\nNumMindflayers: {NumMindflayers}");
			Music.AddPlayCleanWithBattleVote();
			IsBattleWithClean = true;
		}
	}

	private void DisableBattleWithClean()
	{
		if (IsBattleWithClean)
		{
			Log.Debug("Level Additions for P-2 trying to NOT play battle music with clean!");
			Music.SubtractPlayCleanWithBattleVote();
			IsBattleWithClean = false;
		}
	}

	private void OnEnemyDie(EnemyComponents enemy)
	{
		//IL_0007: Unknown result type (might be due to invalid IL or missing references)
		//IL_000c: Unknown result type (might be due to invalid IL or missing references)
		//IL_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Invalid comparison between Unknown and I4
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Invalid comparison between Unknown and I4
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Invalid comparison between Unknown and I4
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Invalid comparison between Unknown and I4
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001b: Invalid comparison between Unknown and I4
		EnemyType enemyType = enemy.Eid.enemyType;
		EnemyType val = enemyType;
		if ((int)val <= 5)
		{
			if ((int)val != 2)
			{
				if ((int)val == 5)
				{
					Log.Debug("P2Additions Detected a Mindflayer death!");
					NumMindflayers--;
				}
			}
			else
			{
				Log.Debug("P2Additions Detected a HideousMass death!");
				NumHideousMasses--;
			}
		}
		else if ((int)val != 9)
		{
			if ((int)val != 30 || !Cheats.IsCheatEnabled("nyxpiri.hydra-mode") || PanopticonRadio.activeSelf)
			{
				return;
			}
			EnemyHydra.SharedData shared = ((Component)enemy).GetComponent<EnemyHydra>().Shared;
			shared.OnDeactivated = (Action)Delegate.Combine(shared.OnDeactivated, (Action)delegate
			{
				if ((Object)(object)PanopticonRadio != (Object)null)
				{
					Object.Destroy((Object)(object)PanopticonRadio.gameObject);
				}
			});
			PanopticonRadio.GetComponent<AudioSource>().time = 22f;
			AudioSource component = PanopticonRadio.GetComponent<AudioSource>();
			component.volume += 0.1f;
			GameObject obj = UnityEngineObjectExtensions.NullInvalid<GameObject>(PanopticonRadio);
			if (obj != null)
			{
				obj.SetActive(true);
			}
		}
		else
		{
			Log.Debug("P2Additions Detected a Virtue death!");
			NumVirtues--;
		}
	}

	private void OnEnemyDestroy(EnemyComponents enemy)
	{
		//IL_0019: Unknown result type (might be due to invalid IL or missing references)
		//IL_001e: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Invalid comparison between Unknown and I4
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_0029: Invalid comparison between Unknown and I4
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Invalid comparison between Unknown and I4
		if (enemy.Eid.dead)
		{
			return;
		}
		EnemyType enemyType = enemy.Eid.enemyType;
		EnemyType val = enemyType;
		if ((int)val != 2)
		{
			if ((int)val != 5)
			{
				if ((int)val == 9)
				{
					Log.Debug("P2Additions Detected a Virtue destruction!");
					NumVirtues--;
				}
			}
			else
			{
				Log.Debug("P2Additions Detected a Mindflayer destruction!");
				NumMindflayers--;
			}
		}
		else
		{
			Log.Debug("P2Additions Detected a HideousMass destruction!");
			NumHideousMasses--;
		}
	}
}
public static class Options
{
	public static ConfigEntry<bool> LogDebugInfo;

	public static ConfigEntry<float> HydraHealthDecayScale;

	public static ConfigEntry<float> HydraDefaultWaitTime;

	public static ConfigEntry<float> HydraMiniBossWaitTime;

	public static ConfigEntry<float> HydraBossWaitTime;

	public static ConfigEntry<float> HydraUltraBossWaitTime;

	public static ConfigEntry<float> HydraKillSoundVolume;

	public static ConfigEntry<int> HydraMaxDepth;

	public static ConfigEntry<int> HydraMaxFromOneBoss;

	public static ConfigEntry<int> HydraMaxFromOne;

	public static ConfigEntry<int> HydraMaxPerUpdate;

	public static ConfigEntry<int> HydraPrefabPoolCapacity;

	public static ConfigEntry<int> HydraPrefabPoolGrowPerUpdate;

	internal static ConfigFile Config;

	public static void Initialize()
	{
		HydraHealthDecayScale = Config.Bind<float>("Balance", "HydraHealthDecayScale", 0.5f, (ConfigDescription)null);
		HydraDefaultWaitTime = Config.Bind<float>("Balance.Normal", "HydraDefaultWaitTime", 0.45f, (ConfigDescription)null);
		HydraMiniBossWaitTime = Config.Bind<float>("", "HydraMiniBossWaitTime", 0.75f, (ConfigDescription)null);
		HydraBossWaitTime = Config.Bind<float>("", "HydraBossWaitTime", 1.5f, (ConfigDescription)null);
		HydraUltraBossWaitTime = Config.Bind<float>("", "HydraUltraBossWaitTime", 2.75f, (ConfigDescription)null);
		HydraMaxFromOneBoss = Config.Bind<int>("Balance.Boss", "HydraMaxFromOneBoss", 6, (ConfigDescription)null);
		HydraMaxDepth = Config.Bind<int>("Balance", "HydraMaxDepth", 16, (ConfigDescription)null);
		HydraMaxFromOne = Config.Bind<int>("Balance.Normal", "HydraMaxFromOne", 12, (ConfigDescription)null);
		HydraMaxPerUpdate = Config.Bind<int>("Performance", "HydraMaxPerFrame", 4, (ConfigDescription)null);
		HydraPrefabPoolCapacity = Config.Bind<int>("Performance", "HydraPrefabPoolCapacity", 20, (ConfigDescription)null);
		HydraPrefabPoolGrowPerUpdate = Config.Bind<int>("Performance", "HydraPrefabPoolGrowPerUpdate", 3, (ConfigDescription)null);
		HydraKillSoundVolume = Config.Bind<float>("Cosmetic", "HydraKillSoundVolume", 2f, (ConfigDescription)null);
		LogDebugInfo = Config.Bind<bool>("Diagnostics", "LogDebugInfo", false, (ConfigDescription)null);
	}
}
[Serializable]
public class FleshDroneHydra : MonoBehaviour
{
	public class SharedData : ScriptableObject
	{
		public FleshPrison Prison = null;
	}

	private EnemyHydra Hydra = null;

	public SharedData Shared = null;

	private bool RegisteredWithPrison = false;

	private bool QueuedDeath = false;

	protected void Start()
	{
		Hydra = ((Component)this).GetComponent<EnemyHydra>();
		Shared = (SharedData)(object)Hydra.Shared.EnemySpecificShared;
		if (Hydra.Depth > 0)
		{
			RegisterWithPrison();
		}
	}

	protected void FixedUpdate()
	{
		if (Hydra.Depth > 0)
		{
			RegisterWithPrison();
			if ((Object)(object)Shared.Prison == (Object)null)
			{
				Hydra.Eid.InstaKill();
				return;
			}
			if (((Component)Shared.Prison).GetComponent<EnemyIdentifier>().dead)
			{
				Hydra.Eid.InstaKill();
				return;
			}
		}
		if (QueuedDeath)
		{
			Hydra.Eid.InstaKill();
		}
	}

	private void RegisterWithPrison()
	{
		if (!RegisteredWithPrison && !Hydra.Eid.dead)
		{
			Shared.Prison?.currentDrones.Add(((Component)this).GetComponent<DroneFlesh>());
			RegisteredWithPrison = true;
		}
	}

	internal void NotifyPrisonDied()
	{
		if (!Hydra.Eid.dead)
		{
			Hydra.Eid.InstaKill();
		}
	}

	internal void QueueDeath()
	{
		QueuedDeath = true;
	}
}
[Serializable]
public class FleshPanopticonHydra : MonoBehaviour
{
	public class SharedData : ScriptableObject
	{
		public uint NumLights = 0u;
	}

	private EnemyHydra Hydra = null;

	private SharedData Shared = null;

	private bool ContributingLights = false;

	protected void Start()
	{
		Hydra = ((Component)this).GetComponent<EnemyHydra>();
		Shared = (SharedData)(object)Hydra.Shared.EnemySpecificShared;
		if (Hydra.Depth > 0 && Shared.NumLights > 2)
		{
			Light[] componentsInChildren = ((Component)((Component)this).transform).GetComponentsInChildren<Light>();
			Light[] array = componentsInChildren;
			foreach (Light val in array)
			{
				if (((Object)((Component)val).gameObject).name.Contains("Spot"))
				{
					Object.Destroy((Object)(object)val);
				}
			}
		}
		else
		{
			Shared.NumLights++;
			ContributingLights = true;
		}
		EnemyHydra hydra = Hydra;
		hydra.PreDeath = (Action)Delegate.Combine(hydra.PreDeath, new Action(PreDeath));
	}

	private void PreDeath()
	{
		if (ContributingLights)
		{
			ContributingLights = false;
			Shared.NumLights--;
		}
		FleshPrison component = ((Component)this).GetComponent<FleshPrison>();
		foreach (DroneFlesh currentDrone in component.currentDrones)
		{
			if ((Object)(object)currentDrone == (Object)null)
			{
				continue;
			}
			if ((Object)(object)((Component)currentDrone).GetComponent<FleshDroneHydra>() == (Object)null)
			{
				EnemyIdentifier component2 = ((Component)currentDrone).GetComponent<EnemyIdentifier>();
				if (component2 != null)
				{
					component2.InstaKill();
				}
			}
			else
			{
				((Component)currentDrone).GetComponent<FleshDroneHydra>().NotifyPrisonDied();
			}
		}
	}

	private void FixedUpdate()
	{
		FleshPrison component = ((Component)this).GetComponent<FleshPrison>();
		if (component.currentDrones.Count <= 0)
		{
			return;
		}
		foreach (DroneFlesh currentDrone in component.currentDrones)
		{
			if ((Object)(object)currentDrone == (Object)null)
			{
				continue;
			}
			FleshDroneHydra component2 = ((Component)currentDrone).GetComponent<FleshDroneHydra>();
			if ((Object)(object)component2 != (Object)null)
			{
				if ((Object)(object)component2.Shared == (Object)null)
				{
					continue;
				}
				component2.Shared.Prison = component;
			}
			if (!ContributingLights)
			{
				component2.QueueDeath();
			}
		}
	}
}