Decompiled source of CGEnemyIcons v1.3.0

CGEnemyIcons.dll

Decompiled 2 months ago
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using CGEnemyIcons.Properties;
using HarmonyLib;
using JadeLib;
using Microsoft.CodeAnalysis;
using PluginConfig.API;
using PluginConfig.API.Decorators;
using PluginConfig.API.Fields;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("CGEnemyIcons")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.3.0.0")]
[assembly: AssemblyInformationalVersion("1.3.0+13c232b0f22de11ccacd74656c33ef381fb38e4c")]
[assembly: AssemblyProduct("CGEnemyIcons")]
[assembly: AssemblyTitle("CGEnemyIcons")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.3.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace CGEnemyIcons
{
	public enum EnemyCategory
	{
		Common,
		Uncommon,
		Special,
		Mass
	}
	[HarmonyPatch]
	internal static class Patches
	{
		private static readonly IEnumerable<SpawnableObject> enemies = Resources.FindObjectsOfTypeAll<SpawnableObjectsDatabase>().SelectMany((SpawnableObjectsDatabase db) => db.enemies);

		private static readonly GameObject iconPrefab = Plugin.Assets.LoadAsset<GameObject>("Enemy Icon");

		private static GameObject iconsCanvas;

		private static GameObject levelStats;

		private static readonly Dictionary<EnemyIdentifier, (EnemyCategory type, bool radiant, GameObject obj)> icons = new Dictionary<EnemyIdentifier, (EnemyCategory, bool, GameObject)>();

		[HarmonyPatch(typeof(EndlessGrid), "Start")]
		[HarmonyPostfix]
		private static void EndlessGrid_Start()
		{
			GameObject obj = Plugin.Assets.LoadAsset<GameObject>("Enemy Icons");
			CanvasController instance = MonoSingleton<CanvasController>.Instance;
			iconsCanvas = Object.Instantiate<GameObject>(obj, (instance != null) ? ((Component)instance).transform.Find("Level Stats Controller") : null);
			CanvasController instance2 = MonoSingleton<CanvasController>.Instance;
			levelStats = ((instance2 != null) ? ((Component)((Component)instance2).transform.Find("Level Stats Controller/Level Stats (1)")).gameObject : null);
			icons.Clear();
		}

		[HarmonyPatch(typeof(EndlessGrid), "SpawnOnGrid")]
		[HarmonyPostfix]
		private static void EndlessGrid_SpawnOnGrid(GameObject obj, bool radiant, GameObject __result, PrefabDatabase ___prefabs)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			EnemyIdentifier eid = ((__result != null) ? __result.GetComponentInChildren<EnemyIdentifier>(true) : null);
			if (eid == null)
			{
				return;
			}
			GameObject val = Object.Instantiate<GameObject>(iconPrefab, Vector2.op_Implicit(Vector2.zero), Quaternion.identity, iconsCanvas.transform);
			((Component)val.transform.Find("Icon")).GetComponent<Image>().sprite = enemies.FirstOrDefault((Func<SpawnableObject, bool>)delegate(SpawnableObject spawnable)
			{
				EnemyIdentifier componentInChildren = spawnable.gameObject.GetComponentInChildren<EnemyIdentifier>(true);
				return ((componentInChildren != null) ? componentInChildren.FullName : null) == eid.FullName;
			})?.gridIcon;
			if (radiant)
			{
				((Component)val.transform.Find("Radiant")).gameObject.SetActive(true);
			}
			((Object)val).name = eid.FullName;
			EnemyCategory item = EnemyCategory.Common;
			if (___prefabs.uncommonEnemies.Any((EndlessEnemy prefab) => (Object)(object)prefab.prefab == (Object)(object)obj))
			{
				item = EnemyCategory.Uncommon;
			}
			else if (___prefabs.specialEnemies.Any((EndlessEnemy prefab) => (Object)(object)prefab.prefab == (Object)(object)obj))
			{
				item = EnemyCategory.Special;
			}
			else if ((Object)(object)obj == (Object)(object)___prefabs.hideousMass)
			{
				item = EnemyCategory.Mass;
			}
			icons.Add(eid, (item, radiant, val));
			foreach (GameObject item2 in from kvp in icons
				orderby (kvp.Value.type, MonoSingleton<EnemyTracker>.Instance.GetEnemyRank(kvp.Key), kvp.Key.FullName, ((Object)kvp.Key).GetInstanceID())
				select kvp.Value.obj)
			{
				item2.transform.SetAsFirstSibling();
			}
		}

		[HarmonyPatch(typeof(EndlessGrid), "Update")]
		[HarmonyPostfix]
		private static void EndlessGrid_Update()
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = iconsCanvas.transform;
			((RectTransform)((transform is RectTransform) ? transform : null)).anchoredPosition = (Vector2)(levelStats.activeSelf ? new Vector2(0f, -220f) : Vector2.zero);
			EnemyIdentifier val = default(EnemyIdentifier);
			(EnemyCategory, bool, GameObject) tuple = default((EnemyCategory, bool, GameObject));
			foreach (KeyValuePair<EnemyIdentifier, (EnemyCategory, bool, GameObject)> icon in icons)
			{
				KeyValuePairExtensions.Deconstruct<EnemyIdentifier, (EnemyCategory, bool, GameObject)>(icon, ref val, ref tuple);
				(EnemyCategory, bool, GameObject) tuple2 = tuple;
				EnemyIdentifier eid = val;
				var (type, flag, val2) = tuple2;
				if ((Object)(object)eid == (Object)null || Settings.HideCategories.Any(((EnemyCategory self, EnemyCategory other) hiders) => hiders.self == type && icons.Any((KeyValuePair<EnemyIdentifier, (EnemyCategory type, bool radiant, GameObject obj)> icon) => !icon.Key.dead && icon.Value.type == hiders.other)))
				{
					val2.SetActive(false);
					continue;
				}
				((Component)val2.transform.Find("Dead")).gameObject.SetActive(eid.dead);
				((Component)val2.transform.Find("Idoled")).gameObject.SetActive(eid.blessed);
				FilterType item2 = Settings.ShowEnemies.FirstOrDefault(((FilterType filter, string name, EnemyCategory type) item) => item.name == eid.FullName && item.type == type).filter;
				OnDeath onDeath = Settings.OnDeath;
				switch (item2)
				{
				case FilterType.RadiantOnly:
					switch (onDeath)
					{
					case OnDeath.Remove:
						val2.SetActive(flag && !eid.dead);
						break;
					case OnDeath.Marker:
						val2.SetActive(flag);
						break;
					case OnDeath.RemoveIfAllDead:
						val2.SetActive(flag && AnyRadiantAlive());
						break;
					}
					break;
				case FilterType.PreferRadiant:
					switch (onDeath)
					{
					case OnDeath.Remove:
						val2.SetActive((flag || !AnyRadiantAlive()) && !eid.dead);
						break;
					case OnDeath.Marker:
						val2.SetActive(flag || !AnyRadiantAlive());
						break;
					case OnDeath.RemoveIfAllDead:
						val2.SetActive(flag ? AnyRadiantAlive() : (!AnyRadiantAlive() && AnyAlive()));
						break;
					}
					break;
				case FilterType.Both:
					switch (onDeath)
					{
					case OnDeath.Remove:
						val2.SetActive(!eid.dead);
						break;
					case OnDeath.Marker:
						val2.SetActive(true);
						break;
					case OnDeath.RemoveIfAllDead:
						val2.SetActive(AnyAlive());
						break;
					}
					break;
				case FilterType.Off:
					val2.SetActive(false);
					break;
				}
				bool AnyAlive()
				{
					return icons.Any((KeyValuePair<EnemyIdentifier, (EnemyCategory type, bool radiant, GameObject obj)> icon) => icon.Key.FullName == eid.FullName && !icon.Key.dead);
				}
				bool AnyRadiantAlive()
				{
					return icons.Any((KeyValuePair<EnemyIdentifier, (EnemyCategory type, bool radiant, GameObject obj)> icon) => icon.Key.FullName == eid.FullName && icon.Value.radiant && !icon.Key.dead);
				}
			}
			iconsCanvas.SetActive(icons.Any((KeyValuePair<EnemyIdentifier, (EnemyCategory type, bool radiant, GameObject obj)> kvp) => kvp.Value.obj.activeSelf));
		}

		[HarmonyPatch(typeof(EndlessGrid), "NextWave")]
		[HarmonyPostfix]
		private static void EndlessGrid_NextWave()
		{
			CollectionExtensions.Do<KeyValuePair<EnemyIdentifier, (EnemyCategory, bool, GameObject)>>((IEnumerable<KeyValuePair<EnemyIdentifier, (EnemyCategory, bool, GameObject)>>)icons, (Action<KeyValuePair<EnemyIdentifier, (EnemyCategory, bool, GameObject)>>)delegate(KeyValuePair<EnemyIdentifier, (EnemyCategory type, bool radiant, GameObject obj)> icon)
			{
				Object.Destroy((Object)(object)icon.Value.obj);
			});
			icons.Clear();
		}
	}
	[BepInPlugin("CGEnemyIcons", "CGEnemyIcons", "1.3.0")]
	internal class Plugin : BaseUnityPlugin
	{
		public static AssetBundle Assets = AssetBundle.LoadFromMemory(Resources.Assets);

		private void Awake()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			Settings.Initialize();
			new Harmony("CGEnemyIcons").PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin CGEnemyIcons is loaded!");
		}
	}
	public enum OnDeath
	{
		Marker,
		Remove,
		RemoveIfAllDead
	}
	public enum FilterType
	{
		Both,
		RadiantOnly,
		PreferRadiant,
		Off
	}
	public static class Settings
	{
		private static EnumField<OnDeath> onDeath;

		private static readonly Dictionary<EnumField<FilterType>, (string name, EnemyCategory type)> showEnemies = new Dictionary<EnumField<FilterType>, (string, EnemyCategory)>();

		private static readonly Dictionary<BoolField, (EnemyCategory self, EnemyCategory other)> hideCategories = new Dictionary<BoolField, (EnemyCategory, EnemyCategory)>();

		public static OnDeath OnDeath => onDeath.value;

		public static IEnumerable<(FilterType filter, string name, EnemyCategory type)> ShowEnemies => showEnemies.Select((KeyValuePair<EnumField<FilterType>, (string name, EnemyCategory type)> kvp) => (kvp.Key.value, kvp.Value.name, kvp.Value.type));

		public static IEnumerable<(EnemyCategory self, EnemyCategory other)> HideCategories => from kvp in hideCategories
			where kvp.Key.value
			select kvp.Value;

		internal static void Initialize()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			PluginConfigurator config = PluginConfigurator.Create("CGEnemyIcons", "CGEnemyIcons");
			config.icon = Plugin.Assets.LoadAsset<Sprite>("Icon");
			onDeath = new EnumField<OnDeath>(config.rootPanel, "ACTION ON DEATH", "onDeath", OnDeath.Marker);
			onDeath.SetEnumDisplayName(OnDeath.Marker, "CROSS OUT");
			onDeath.SetEnumDisplayName(OnDeath.Remove, "REMOVE");
			onDeath.SetEnumDisplayName(OnDeath.RemoveIfAllDead, "REMOVE IF ALL DEAD");
			new ConfigHeader(config.rootPanel, "ENEMY TYPES", 24);
			PrefabDatabase val = Addressables.LoadAssetAsync<PrefabDatabase>((object)"Assets/Data/Cyber Grind Patterns/Data/Prefab Database.asset").WaitForCompletion();
			AddEnemies(val.meleeEnemies.Concat(val.projectileEnemies), EnemyCategory.Common);
			AddEnemies(val.uncommonEnemies, EnemyCategory.Uncommon);
			AddEnemies(val.specialEnemies, EnemyCategory.Special);
			CreateCategory(EnemyCategory.Mass, "HIDEOUS MASSES");
			AddEnemy(val.hideousMass, EnemyCategory.Mass);
			void AddEnemies(IEnumerable<EndlessEnemy> enemies, EnemyCategory category)
			{
				CreateCategory(category, EnumExtensions.Name<EnemyCategory>(category).ToUpperInvariant() + " ENEMIES");
				CollectionExtensions.Do<EndlessEnemy>(enemies, (Action<EndlessEnemy>)delegate(EndlessEnemy enemy)
				{
					AddEnemy(enemy.prefab, category);
				});
			}
			void AddEnemy(GameObject enemy, EnemyCategory category)
			{
				string fullName = enemy.GetComponentInChildren<EnemyIdentifier>(true).FullName;
				EnumField<FilterType> val2 = new EnumField<FilterType>(config.rootPanel, "SHOW " + fullName.ToUpperInvariant(), fullName, FilterType.Both);
				val2.SetEnumDisplayName(FilterType.Both, "YES");
				val2.SetEnumDisplayName(FilterType.RadiantOnly, "RADIANT ONLY");
				val2.SetEnumDisplayName(FilterType.PreferRadiant, "PREFER RADIANT");
				val2.SetEnumDisplayName(FilterType.Off, "NO");
				showEnemies.Add(val2, (fullName, category));
			}
			void CreateCategory(EnemyCategory category, string categoryName)
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				new ConfigHeader(config.rootPanel, categoryName, 18);
				EnumExtensions.DoIf<EnemyCategory>(category, (Func<EnemyCategory, bool>)((EnemyCategory T) => T != category), (Action<EnemyCategory>)delegate(EnemyCategory T)
				{
					//IL_005a: Unknown result type (might be due to invalid IL or missing references)
					//IL_0070: Expected O, but got Unknown
					hideCategories.Add(new BoolField(config.rootPanel, "HIDE IF " + EnumExtensions.Name<EnemyCategory>(T).ToUpperInvariant() + " ALIVE", "hide" + EnumExtensions.Name<EnemyCategory>(category).ToLowerInvariant() + "if" + EnumExtensions.Name<EnemyCategory>(T).ToLowerInvariant(), false), (category, T));
				});
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "CGEnemyIcons";

		public const string PLUGIN_NAME = "CGEnemyIcons";

		public const string PLUGIN_VERSION = "1.3.0";
	}
}
namespace CGEnemyIcons.Properties
{
	[GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
	[DebuggerNonUserCode]
	[CompilerGenerated]
	internal class Resources
	{
		private static ResourceManager resourceMan;

		private static CultureInfo resourceCulture;

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static ResourceManager ResourceManager
		{
			get
			{
				if (resourceMan == null)
				{
					resourceMan = new ResourceManager("CGEnemyIcons.Properties.Resources", typeof(Resources).Assembly);
				}
				return resourceMan;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Advanced)]
		internal static CultureInfo Culture
		{
			get
			{
				return resourceCulture;
			}
			set
			{
				resourceCulture = value;
			}
		}

		internal static byte[] Assets => (byte[])ResourceManager.GetObject("Assets", resourceCulture);

		internal Resources()
		{
		}
	}
}