Decompiled source of IdentityCrisis v1.1.0

IdentityCrisis.dll

Decompiled 7 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PluginConfig.API;
using PluginConfig.API.Fields;
using UnityEngine;
using UnityEngine.SceneManagement;

[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: AssemblyCompany("IdentityCrisis")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("IdentityCrisis")]
[assembly: AssemblyTitle("IdentityCrisis")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
[BepInPlugin("com.flame.ultrakill.identitycrisis", "Identity Crisis Mod", "1.9.6")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class IdentityCrisisPlugin : BaseUnityPlugin
{
	public static IdentityCrisisPlugin Instance = null;

	public static FloatField MorphIntervalField = null;

	public static List<GameObject> MasterEnemyPrefabs = new List<GameObject>();

	public static List<GameObject> ActiveClones = new List<GameObject>();

	public static float MorphInterval => (MorphIntervalField != null) ? MorphIntervalField.value : 5f;

	private void Awake()
	{
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Expected O, but got Unknown
		//IL_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0081: Expected O, but got Unknown
		Instance = this;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[IdentityCrisis] Initializing v1.9.6...");
		try
		{
			PluginConfigurator val = PluginConfigurator.Create("Identity Crisis", "identitycrisis");
			MorphIntervalField = new FloatField(val.rootPanel, "Morph Interval (Seconds)", "identitycrisis.morphinterval", 5f, 0.5f, 60f);
		}
		catch (Exception ex)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("[IdentityCrisis] Config error: " + ex.Message));
		}
		Harmony val2 = new Harmony("com.flame.ultrakill.identitycrisis");
		val2.PatchAll();
		SceneManager.sceneLoaded += OnSceneLoaded;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"[IdentityCrisis] Mod loaded successfully!");
	}

	private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
	{
		ActiveClones.Clear();
		PopulateMasterEnemyPool();
	}

	public void PopulateMasterEnemyPool()
	{
		MasterEnemyPrefabs.Clear();
		try
		{
			SpawnableObjectsDatabase[] array = Resources.FindObjectsOfTypeAll<SpawnableObjectsDatabase>();
			if (array == null || array.Length == 0 || array[0].enemies == null)
			{
				return;
			}
			SpawnableObject[] enemies = array[0].enemies;
			foreach (SpawnableObject val in enemies)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)val.gameObject != (Object)null)
				{
					MasterEnemyPrefabs.Add(val.gameObject);
				}
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)$"[IdentityCrisis] Successfully loaded {MasterEnemyPrefabs.Count} global enemy prefabs from database.");
		}
		catch (Exception arg)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)$"[IdentityCrisis] Error populating master pool: {arg}");
		}
	}

	public static void CleanupAllClones()
	{
		foreach (GameObject activeClone in ActiveClones)
		{
			if ((Object)(object)activeClone != (Object)null)
			{
				Object.Destroy((Object)(object)activeClone);
			}
		}
		ActiveClones.Clear();
		Instance?.LogDebug("[IdentityCrisis] Cleared all dynamic clone entities due to checkpoint reload.");
	}

	public void LogDebug(string message)
	{
		((BaseUnityPlugin)this).Logger.LogInfo((object)("[IdentityCrisis - DEBUG] " + message));
	}
}
[HarmonyPatch(typeof(NewMovement), "Respawn")]
public class NewMovementRespawnPatch
{
	public static void Postfix()
	{
		IdentityCrisisPlugin.CleanupAllClones();
	}
}
[HarmonyPatch(typeof(EnemyIdentifier), "Awake")]
public class EnemyIdentifierAwakePatch
{
	public static void Postfix(EnemyIdentifier __instance)
	{
		if ((Object)(object)__instance != (Object)null && (Object)(object)((Component)__instance).gameObject != (Object)null && (Object)(object)((Component)__instance).GetComponent<IdentityCrisisTracker>() == (Object)null)
		{
			((Component)__instance).gameObject.AddComponent<IdentityCrisisTracker>();
		}
	}
}
public class IdentityCrisisTracker : MonoBehaviour
{
	private EnemyIdentifier? enemyID;

	private float timer = 0f;

	private float nextMorphTime = 5f;

	public bool isMorphing = false;

	private void Start()
	{
		enemyID = ((Component)this).GetComponent<EnemyIdentifier>();
		ResetTimer();
	}

	private void OnEnable()
	{
		isMorphing = false;
		ResetTimer();
	}

	private void Update()
	{
		if (Time.timeScale != 0f && !((Object)(object)enemyID == (Object)null) && !enemyID.dead && !isMorphing)
		{
			timer += Time.deltaTime;
			if (timer >= nextMorphTime)
			{
				TriggerIndividualMorph();
				ResetTimer();
			}
		}
	}

	private void ResetTimer()
	{
		timer = 0f;
		nextMorphTime = IdentityCrisisPlugin.MorphInterval + Random.Range(0f, 2f);
	}

	private void TriggerIndividualMorph()
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		//IL_004d: 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_0075: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)enemyID == (Object)null || enemyID.dead || isMorphing)
		{
			return;
		}
		isMorphing = true;
		try
		{
			Vector3 position = ((Component)this).transform.position;
			Quaternion rotation = ((Component)this).transform.rotation;
			IdentityCrisisPlugin.Instance.LogDebug("[MORPH] Morphing '" + ((Object)((Component)this).gameObject).name + "' safely via native encounter notification.");
			SpawnGlobalRandomEnemy(position, rotation);
			int num = 0;
			bool flag = (Object)(object)MonoSingleton<StatsManager>.Instance != (Object)null;
			if (flag)
			{
				num = MonoSingleton<StatsManager>.Instance.kills;
			}
			enemyID.InstaKill();
			if (flag && MonoSingleton<StatsManager>.Instance.kills > num)
			{
				StatsManager instance = MonoSingleton<StatsManager>.Instance;
				instance.kills--;
				IdentityCrisisPlugin.Instance.LogDebug("[MORPH] Successfully rolled back stat kill count for morph transition.");
			}
		}
		catch (Exception arg)
		{
			IdentityCrisisPlugin.Instance.LogDebug($"[MORPH ERROR EXCEPTION] {arg}");
			isMorphing = false;
		}
	}

	private void SpawnGlobalRandomEnemy(Vector3 pos, Quaternion rot)
	{
		//IL_0079: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			List<GameObject> masterEnemyPrefabs = IdentityCrisisPlugin.MasterEnemyPrefabs;
			if (masterEnemyPrefabs == null || masterEnemyPrefabs.Count == 0)
			{
				IdentityCrisisPlugin.Instance.PopulateMasterEnemyPool();
				masterEnemyPrefabs = IdentityCrisisPlugin.MasterEnemyPrefabs;
				if (masterEnemyPrefabs == null || masterEnemyPrefabs.Count == 0)
				{
					IdentityCrisisPlugin.Instance.LogDebug("[SPAWN ERROR] Master pool is still empty!");
					return;
				}
			}
			GameObject val = masterEnemyPrefabs[Random.Range(0, masterEnemyPrefabs.Count)];
			if ((Object)(object)val != (Object)null)
			{
				GameObject val2 = Object.Instantiate<GameObject>(val, pos, rot);
				IdentityCrisisPlugin.ActiveClones.Add(val2);
				IdentityCrisisPlugin.Instance.LogDebug("[SPAWN SUCCESS] Morph result: " + ((Object)val).name + " -> Spawned: " + ((Object)val2).name);
			}
		}
		catch (Exception arg)
		{
			IdentityCrisisPlugin.Instance.LogDebug($"[SPAWN ERROR EXCEPTION] {arg}");
		}
	}
}