using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
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.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CGEnemyIcons")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.4.0.0")]
[assembly: AssemblyInformationalVersion("1.4.0+5cfa43aa51ca277e4453e19f50710be2de2a899a")]
[assembly: AssemblyProduct("CGEnemyIcons")]
[assembly: AssemblyTitle("CGEnemyIcons")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.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
{
internal enum EnemyCategory
{
Common,
Uncommon,
Special,
Mass
}
internal readonly record struct IconInfo(EnemyIdentifier Enemy, EnemyCategory Type, bool IsRadiant, GameObject IconObject) : IComparable<IconInfo>
{
public bool Equals(IconInfo? other)
{
if (other.HasValue)
{
return (Object)(object)other.Value.Enemy == (Object)(object)Enemy;
}
return false;
}
public override int GetHashCode()
{
return ((Object)Enemy).GetInstanceID();
}
public int CompareTo(IconInfo other)
{
int num = Type.CompareTo(other.Type);
if (num != 0)
{
return num;
}
int num2 = MonoSingleton<EnemyTracker>.Instance.GetEnemyRank(Enemy).CompareTo(MonoSingleton<EnemyTracker>.Instance.GetEnemyRank(other.Enemy));
if (num2 != 0)
{
return num2;
}
int num3 = string.Compare(Enemy.FullName, other.Enemy.FullName, StringComparison.InvariantCultureIgnoreCase);
if (num3 == 0)
{
return ((Object)Enemy).GetInstanceID().CompareTo(((Object)other.Enemy).GetInstanceID());
}
return num3;
}
}
[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 SortedSet<IconInfo> icons = new SortedSet<IconInfo>();
[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)
{
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 type = EnemyCategory.Common;
if (___prefabs.uncommonEnemies.Any((EndlessEnemy prefab) => (Object)(object)prefab.prefab == (Object)(object)obj))
{
type = EnemyCategory.Uncommon;
}
else if (___prefabs.specialEnemies.Any((EndlessEnemy prefab) => (Object)(object)prefab.prefab == (Object)(object)obj))
{
type = EnemyCategory.Special;
}
else if ((Object)(object)obj == (Object)(object)___prefabs.hideousMass)
{
type = EnemyCategory.Mass;
}
icons.Add(new IconInfo(eid, type, radiant, val));
CollectionExtensions.Do<IconInfo>((IEnumerable<IconInfo>)icons, (Action<IconInfo>)delegate(IconInfo icon2)
{
icon2.IconObject.transform.SetAsLastSibling();
});
}
}
[HarmonyPatch(typeof(EndlessGrid), "Update")]
[HarmonyPostfix]
private static void EndlessGrid_Update()
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//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)
((RectTransform)iconsCanvas.transform).anchoredPosition = (Vector2)(levelStats.activeSelf ? new Vector2(0f, -220f) : Vector2.zero);
foreach (IconInfo icon in icons)
{
var (eid, type, flag2, val3) = (IconInfo)(ref icon);
if (!Object.op_Implicit((Object)(object)eid) || Settings.HideCategories.Any(((EnemyCategory self, EnemyCategory other) hiders) => hiders.self == type && icons.Any((IconInfo otherIcon) => otherIcon.Type == hiders.other && !otherIcon.Enemy.dead)))
{
val3.SetActive(false);
continue;
}
((Component)val3.transform.Find("Dead")).gameObject.SetActive(eid.dead);
((Component)val3.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:
val3.SetActive(flag2 && !eid.dead);
break;
case OnDeath.Marker:
val3.SetActive(flag2);
break;
case OnDeath.RemoveIfAllDead:
val3.SetActive(flag2 && AnyRadiantAlive());
break;
}
break;
case FilterType.PreferRadiant:
switch (onDeath)
{
case OnDeath.Remove:
val3.SetActive((flag2 || !AnyRadiantAlive()) && !eid.dead);
break;
case OnDeath.Marker:
val3.SetActive(flag2 || !AnyRadiantAlive());
break;
case OnDeath.RemoveIfAllDead:
val3.SetActive(flag2 ? AnyRadiantAlive() : (!AnyRadiantAlive() && AnyAlive()));
break;
}
break;
case FilterType.Both:
switch (onDeath)
{
case OnDeath.Remove:
val3.SetActive(!eid.dead);
break;
case OnDeath.Marker:
val3.SetActive(true);
break;
case OnDeath.RemoveIfAllDead:
val3.SetActive(AnyAlive());
break;
}
break;
case FilterType.Off:
val3.SetActive(false);
break;
}
bool AnyAlive()
{
return icons.Any((IconInfo otherIcon) => otherIcon.Enemy.FullName == eid.FullName && !otherIcon.Enemy.dead);
}
bool AnyRadiantAlive()
{
return icons.Any((IconInfo otherIcon) => otherIcon.Enemy.FullName == eid.FullName && otherIcon.IsRadiant && !otherIcon.Enemy.dead);
}
}
iconsCanvas.SetActive(icons.Any((IconInfo icon) => icon.IconObject.activeSelf));
}
[HarmonyPatch(typeof(EndlessGrid), "NextWave")]
[HarmonyPostfix]
private static void EndlessGrid_NextWave()
{
CollectionExtensions.Do<IconInfo>((IEnumerable<IconInfo>)icons, (Action<IconInfo>)delegate(IconInfo icon)
{
Object.Destroy((Object)(object)icon.IconObject);
});
icons.Clear();
}
}
[BepInPlugin("CGEnemyIcons", "CGEnemyIcons", "1.4.0")]
internal class Plugin : BaseUnityPlugin
{
public static readonly AssetBundle Assets = AssetBundle.LoadFromFile(Path.Combine(ModDir, "cgenemyicons.bundle"));
private static string ModDir => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
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!");
}
}
internal enum OnDeath
{
Marker,
Remove,
RemoveIfAllDead
}
internal enum FilterType
{
Both,
RadiantOnly,
PreferRadiant,
Off
}
internal 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 MyPluginInfo
{
public const string PLUGIN_GUID = "CGEnemyIcons";
public const string PLUGIN_NAME = "CGEnemyIcons";
public const string PLUGIN_VERSION = "1.4.0";
}
}
namespace System.Runtime.CompilerServices
{
public class IsExternalInit
{
}
}