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()
{
}
}
}