Decompiled source of CGEnemyIcons v1.2.0

CGEnemyIcons.dll

Decompiled 2 weeks 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 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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("CGEnemyIcons")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0")]
[assembly: AssemblyProduct("CGEnemyIcons")]
[assembly: AssemblyTitle("CGEnemyIcons")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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 OnDeath
	{
		Marker,
		Remove,
		RemoveIfAllDead
	}
	public enum FilterType
	{
		Off,
		RadiantOnly,
		PreferRadiant,
		Both
	}
	public static class Config
	{
		public static EnumField<OnDeath> onDeath;

		public static List<(string name, EnemyCategory type, EnumField<FilterType> field)> showEnemies = new List<(string, EnemyCategory, EnumField<FilterType>)>();

		public static Dictionary<(EnemyCategory self, EnemyCategory other), BoolField> hideEnemies = new Dictionary<(EnemyCategory, EnemyCategory), BoolField>();

		public static void Init()
		{
			//IL_0092: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: 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.SetEnumDisplayNames<OnDeath>(new string[3] { "Cross Out", "Remove", "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();
			new ConfigHeader(config.rootPanel, "Common Enemies", 18);
			CreateHiders(EnemyCategory.Commons);
			EndlessEnemy[] meleeEnemies = val.meleeEnemies;
			foreach (EndlessEnemy val2 in meleeEnemies)
			{
				string fullName = val2.prefab.GetComponentInChildren<EnemyIdentifier>(true).FullName;
				showEnemies.Add((fullName, EnemyCategory.Commons, new EnumField<FilterType>(config.rootPanel, "Show " + fullName, fullName, FilterType.Both)));
			}
			EndlessEnemy[] projectileEnemies = val.projectileEnemies;
			foreach (EndlessEnemy val3 in projectileEnemies)
			{
				string fullName2 = val3.prefab.GetComponentInChildren<EnemyIdentifier>(true).FullName;
				showEnemies.Add((fullName2, EnemyCategory.Commons, new EnumField<FilterType>(config.rootPanel, "Show " + fullName2, fullName2, FilterType.Both)));
			}
			new ConfigHeader(config.rootPanel, "Uncommon Enemies", 18);
			CreateHiders(EnemyCategory.Uncommons);
			EndlessEnemy[] uncommonEnemies = val.uncommonEnemies;
			foreach (EndlessEnemy val4 in uncommonEnemies)
			{
				string fullName3 = val4.prefab.GetComponentInChildren<EnemyIdentifier>(true).FullName;
				showEnemies.Add((fullName3, EnemyCategory.Uncommons, new EnumField<FilterType>(config.rootPanel, "Show " + fullName3, fullName3, FilterType.Both)));
			}
			new ConfigHeader(config.rootPanel, "Special Enemies", 18);
			CreateHiders(EnemyCategory.Specials);
			EndlessEnemy[] specialEnemies = val.specialEnemies;
			foreach (EndlessEnemy val5 in specialEnemies)
			{
				string fullName4 = val5.prefab.GetComponentInChildren<EnemyIdentifier>(true).FullName;
				showEnemies.Add((fullName4, EnemyCategory.Specials, new EnumField<FilterType>(config.rootPanel, "Show " + fullName4, fullName4, FilterType.Both)));
			}
			new ConfigHeader(config.rootPanel, "Hideous Masses", 18);
			CreateHiders(EnemyCategory.Masses);
			string fullName5 = val.hideousMass.GetComponentInChildren<EnemyIdentifier>(true).FullName;
			showEnemies.Add((fullName5, EnemyCategory.Masses, new EnumField<FilterType>(config.rootPanel, "Show " + fullName5, fullName5, FilterType.Both)));
			foreach (EnumField<FilterType> item in showEnemies.Select(((string name, EnemyCategory type, EnumField<FilterType> field) i) => i.field))
			{
				item.SetEnumDisplayNames<FilterType>(new string[4] { "No", "Radiant Only", "Prefer Radiant", "Yes" });
			}
			void CreateHiders(EnemyCategory self)
			{
				self.DoIf((EnemyCategory T) => T != self, delegate(EnemyCategory T)
				{
					//IL_0057: Unknown result type (might be due to invalid IL or missing references)
					//IL_0061: Expected O, but got Unknown
					hideEnemies.Add((self, T), new BoolField(config.rootPanel, "Hide if " + T.Name() + " Alive", "hide" + self.Name() + "If" + T.Name(), false));
				});
			}
		}
	}
	public static class KeyValuePairExtensions
	{
		public static void Deconstruct<TKey, TValue>(this KeyValuePair<TKey, TValue> kvp, out TKey key, out TValue value)
		{
			key = kvp.Key;
			value = kvp.Value;
		}
	}
	public static class PluginConfigExtensions
	{
		public static void SetEnumDisplayNames<T>(this EnumField<T> field, params string[] names) where T : struct, Enum
		{
			T[] array = Enum.GetValues(typeof(T)) as T[];
			for (int i = 0; i < Math.Min(array.Length, names.Length); i++)
			{
				field.SetEnumDisplayName(array[i], names[i]);
			}
		}
	}
	public static class EnumExtensions
	{
		public static void Do<T>(this T _, Action<T> action) where T : Enum
		{
			CollectionExtensions.Do<T>((IEnumerable<T>)(Enum.GetValues(typeof(T)) as T[]), action);
		}

		public static void DoIf<T>(this T _, Func<T, bool> condition, Action<T> action) where T : Enum
		{
			CollectionExtensions.DoIf<T>((IEnumerable<T>)(Enum.GetValues(typeof(T)) as T[]), condition, action);
		}

		public static string Name<T>(this T value) where T : Enum
		{
			return Enum.GetName(typeof(T), value);
		}
	}
	public enum EnemyCategory
	{
		Commons,
		Uncommons,
		Specials,
		Masses
	}
	[HarmonyPatch]
	internal static class Patches
	{
		public static IEnumerable<SpawnableObject> enemies;

		public static GameObject iconsCanvas;

		public static GameObject iconPrefab;

		public static GameObject levelStats;

		public static 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()
		{
			enemies = Resources.FindObjectsOfTypeAll<SpawnableObjectsDatabase>().SelectMany((SpawnableObjectsDatabase db) => db.enemies);
			iconsCanvas = Object.Instantiate<GameObject>(Plugin.assets.LoadAsset<GameObject>("Enemy Icons"), ((Component)MonoSingleton<CanvasController>.Instance).transform.Find("Level Stats Controller"));
			levelStats = ((Component)((Component)MonoSingleton<CanvasController>.Instance).transform.Find("Level Stats Controller/Level Stats (1)")).gameObject;
			iconPrefab = Plugin.assets.LoadAsset<GameObject>("Enemy Icon");
		}

		[HarmonyPatch(typeof(EndlessGrid), "SpawnOnGrid")]
		[HarmonyPostfix]
		private static void EndlessGrid_SpawnOnGrid(GameObject obj, bool radiant, ref GameObject __result, PrefabDatabase ___prefabs)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			GameObject obj2 = __result;
			EnemyIdentifier eid = ((obj2 != null) ? obj2.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.Commons;
			if (___prefabs.uncommonEnemies.Any((EndlessEnemy prefab) => (Object)(object)prefab.prefab == (Object)(object)obj))
			{
				item = EnemyCategory.Uncommons;
			}
			else if (___prefabs.specialEnemies.Any((EndlessEnemy prefab) => (Object)(object)prefab.prefab == (Object)(object)obj))
			{
				item = EnemyCategory.Specials;
			}
			else if ((Object)(object)obj == (Object)(object)___prefabs.hideousMass)
			{
				item = EnemyCategory.Masses;
			}
			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_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: 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);
			foreach (KeyValuePair<EnemyIdentifier, (EnemyCategory, bool, GameObject)> icon in icons)
			{
				KeyValuePairExtensions.Deconstruct(icon, out var key, out var value);
				(EnemyCategory, bool, GameObject) tuple = value;
				EnemyIdentifier eid = key;
				var (type, flag, val) = tuple;
				if (Config.hideEnemies.Any((KeyValuePair<(EnemyCategory self, EnemyCategory other), BoolField> hiders) => hiders.Key.self == type && hiders.Value.value && icons.Any((KeyValuePair<EnemyIdentifier, (EnemyCategory type, bool radiant, GameObject obj)> icon) => !icon.Key.dead && icon.Value.type == hiders.Key.other)))
				{
					val.SetActive(false);
					continue;
				}
				((Component)val.transform.Find("Dead")).gameObject.SetActive(eid.dead);
				((Component)val.transform.Find("Idoled")).gameObject.SetActive(eid.blessed);
				(FilterType?, OnDeath) tuple3 = (Config.showEnemies.FirstOrDefault(((string name, EnemyCategory type, EnumField<FilterType> field) item) => item.name == eid.FullName && item.type == type).field?.value, Config.onDeath.value);
				(FilterType?, OnDeath) tuple4 = tuple3;
				switch (tuple4.Item1)
				{
				case FilterType.Off:
				{
					OnDeath item2 = tuple4.Item2;
					if ((uint)item2 <= 2u)
					{
						val.SetActive(false);
					}
					continue;
				}
				case FilterType.RadiantOnly:
					switch (tuple4.Item2)
					{
					case OnDeath.Remove:
						val.SetActive(flag && !eid.dead);
						break;
					case OnDeath.Marker:
						val.SetActive(flag);
						break;
					case OnDeath.RemoveIfAllDead:
						val.SetActive(flag && AnyRadiantAlive());
						break;
					}
					continue;
				case FilterType.PreferRadiant:
					switch (tuple4.Item2)
					{
					case OnDeath.Remove:
						val.SetActive((flag || !AnyRadiantAlive()) && !eid.dead);
						break;
					case OnDeath.Marker:
						val.SetActive(flag || !AnyRadiantAlive());
						break;
					case OnDeath.RemoveIfAllDead:
						val.SetActive((flag && AnyRadiantAlive()) || (!flag && !AnyRadiantAlive() && AnyAlive()));
						break;
					}
					continue;
				case FilterType.Both:
					switch (tuple4.Item2)
					{
					case OnDeath.Remove:
						break;
					case OnDeath.Marker:
						goto IL_02ef;
					case OnDeath.RemoveIfAllDead:
						goto end_IL_015a;
					default:
						continue;
					}
					goto IL_02d8;
				case null:
					switch (tuple4.Item2)
					{
					case OnDeath.Remove:
						break;
					case OnDeath.Marker:
						goto IL_02ef;
					case OnDeath.RemoveIfAllDead:
						goto end_IL_015a;
					default:
						continue;
					}
					goto IL_02d8;
				default:
					continue;
					IL_02ef:
					val.SetActive(true);
					continue;
					IL_02d8:
					val.SetActive(!eid.dead);
					continue;
					end_IL_015a:
					break;
				}
				val.SetActive(AnyAlive());
				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.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		public static AssetBundle assets;

		private void Awake()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			assets = AssetBundle.LoadFromMemory(Resources.Assets);
			Config.Init();
			new Harmony("CGEnemyIcons").PatchAll();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin CGEnemyIcons is loaded!");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "CGEnemyIcons";

		public const string PLUGIN_NAME = "CGEnemyIcons";

		public const string PLUGIN_VERSION = "1.1.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)
				{
					ResourceManager resourceManager = new ResourceManager("CGEnemyIcons.Properties.Resources", typeof(Resources).Assembly);
					resourceMan = resourceManager;
				}
				return resourceMan;
			}
		}

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

		internal static byte[] Assets
		{
			get
			{
				object @object = ResourceManager.GetObject("Assets", resourceCulture);
				return (byte[])@object;
			}
		}

		internal Resources()
		{
		}
	}
}