Decompiled source of Crossover v1.1.1

plugins\Crossover.dll

Decompiled a week ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Notiffy.API;
using PluginConfig.API;
using PluginConfig.API.Decorators;
using PluginConfig.API.Fields;
using TMPro;
using UnityEngine;
using UnityEngine.SceneManagement;
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("Crossover")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+06d55002185a931d843a93a72ce8f86a5ce97854")]
[assembly: AssemblyProduct("Crossover")]
[assembly: AssemblyTitle("Crossover")]
[assembly: AssemblyVersion("1.0.0.0")]
[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.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]
	[Microsoft.CodeAnalysis.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;
		}
	}
	[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 Crossover
{
	public class ConfigManager
	{
		public static PluginConfigurator config;

		public static BoolField Enable;

		public static ColorField AccentColor;

		public static BoolField EnableTrackers;

		public static IntField TrackerThreshold;

		public static Dictionary<string, BoolField> ForceTrackEnemies;

		public static BoolField TrackerIgnorePuppets;

		public static BoolField TrackerUseSpecificEnemyIcons;

		public static BoolField TrackerShowEnemyNames;

		public static ColorField TrackerColor;

		public static FloatField StartScale;

		public static FloatField EndScale;

		public static FloatField EnemyHealthThreshold;

		public static FloatSliderField CrossMarkOpacity;

		public static FloatField ScalingDuration;

		public static FloatField ScalingDelay;

		public static FloatField VisibleDuration;

		public static FloatField TrackerScale;

		public static FloatSliderField TrackerMarkOpacity;

		public static StringField LastVersion;

		public static void Initialize()
		{
		}

		public static bool IsEnemyForceTracked(EnemyType type)
		{
			return ForceTrackEnemies[((object)(EnemyType)(ref type)).ToString()].value;
		}

		private static void CreateTrackerForcedEnemies()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			ConfigPanel val = new ConfigPanel(config.rootPanel, "Always track enemy types...", "forcedTrackEnemies");
			new ConfigHeader(config.rootPanel, "", 10);
			new ConfigHeader(val, "You can, for example, force Powers and Mindflayers to always have an indicator shown. FUCK POWERS FUCK POWERS FUCK POWERS I HATE POWERS", 12, (TextAlignmentOptions)513);
			string[] names = Enum.GetNames(typeof(EnemyType));
			Array.Sort(names);
			foreach (string text in names)
			{
				ForceTrackEnemies[text] = new BoolField(val, text, "forceTrack" + text, false);
			}
		}

		static ConfigManager()
		{
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Expected O, but got Unknown
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Expected O, but got Unknown
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Expected O, but got Unknown
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Expected O, but got Unknown
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Expected O, but got Unknown
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Expected O, but got Unknown
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_023a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Expected O, but got Unknown
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Expected O, but got Unknown
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Expected O, but got Unknown
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Expected O, but got Unknown
			//IL_02d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Expected O, but got Unknown
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Expected O, but got Unknown
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Expected O, but got Unknown
			//IL_033b: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0364: Expected O, but got Unknown
			//IL_038c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0396: Expected O, but got Unknown
			//IL_03af: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b9: Expected O, but got Unknown
			ForceTrackEnemies = new Dictionary<string, BoolField>();
			config = PluginConfigurator.Create("Crossover", "com.github.end-4.crossover");
			string text = Path.Combine(Plugin.workingDir, "icon.png");
			if (File.Exists(text))
			{
				config.SetIconWithURL(text);
			}
			new ConfigHeader(config.rootPanel, "", 10);
			new ConfigHeader(config.rootPanel, "-- <color=#db1e39>DEATH CROSSES</color> --", 22);
			Enable = new BoolField(config.rootPanel, "Enable death crosses", "enable", true);
			AccentColor = new ColorField(config.rootPanel, "Cross accent color", "accentColor", new Color(73f / 85f, 0.11764706f, 19f / 85f));
			new ConfigHeader(config.rootPanel, "", 10);
			new ConfigHeader(config.rootPanel, "-- <color=#f1b613>ENEMY TRACKERS</color> --", 22);
			new ConfigHeader(config.rootPanel, "Shows pointers for enemy locations even when they're out of view", 12);
			EnableTrackers = new BoolField(config.rootPanel, "Enable tracker icons", "enableTrackers", false);
			TrackerThreshold = new IntField(config.rootPanel, "Reveal last remaining x enemies", "trackerThreshold", 5);
			CreateTrackerForcedEnemies();
			TrackerIgnorePuppets = new BoolField(config.rootPanel, "Ignore puppets (blood bois)", "trackerIgnorePuppets", false);
			TrackerUseSpecificEnemyIcons = new BoolField(config.rootPanel, "Use specific enemy type icons", "trackerUseSpecificEnemyIcons", true);
			TrackerShowEnemyNames = new BoolField(config.rootPanel, "Show enemy names", "trackerShowEnemyNames", true);
			TrackerColor = new ColorField(config.rootPanel, "Tracker accent color", "trackerColor", new Color(0.94509804f, 0.7137255f, 0.07450981f));
			new ConfigHeader(config.rootPanel, "", 10);
			new ConfigHeader(config.rootPanel, "-- <color=#ff7f27>ADVANCED</color> --", 22);
			new ConfigHeader(config.rootPanel, "// <color=#db1e39>Death crosses</color>", 16, (TextAlignmentOptions)513);
			StartScale = new FloatField(config.rootPanel, "Cross starting scale", "startScale", 2f);
			EndScale = new FloatField(config.rootPanel, "Cross ending scale", "endScale", 0.35f);
			EnemyHealthThreshold = new FloatField(config.rootPanel, "Cross enemy health threshold", "enemyHealthThreshold", 0f);
			CrossMarkOpacity = new FloatSliderField(config.rootPanel, "Cross mark opacity", "crossMarkOpacity", new Tuple<float, float>(0f, 1f), 1f);
			ScalingDelay = new FloatField(config.rootPanel, "Scaling delay", "scalingDelay", 0f);
			ScalingDuration = new FloatField(config.rootPanel, "Scaling duration", "scalingDuration", 0.1333f);
			VisibleDuration = new FloatField(config.rootPanel, "Visible duration", "visibleDuration", 0.5333f);
			new ConfigHeader(config.rootPanel, "// <color=#f1b613>Enemy trackers</color>", 16, (TextAlignmentOptions)513);
			TrackerScale = new FloatField(config.rootPanel, "Tracker mark scale", "trackerScale", 1f);
			TrackerMarkOpacity = new FloatSliderField(config.rootPanel, "Tracker mark opacity", "trackerMarkOpacity", new Tuple<float, float>(0f, 1f), 0.7f);
			LastVersion = new StringField(config.rootPanel, "Last version", "lastVersion", "0.0.0");
			((ConfigField)LastVersion).hidden = true;
		}
	}
	public class CrossBehavior : EnemyTrackingBehavior
	{
		private enum State
		{
			Hidden,
			Marking
		}

		public bool startMarkImmediately = true;

		public float markLifetime = 0.5333f;

		public float scalingDelay;

		public float scalingDuration = 0.1333f;

		public float startScale = 1f;

		public float endScale = 0.2f;

		public Tuple<float, Color>[] colorSteps = Array.Empty<Tuple<float, Color>>();

		private RectTransform rectTransform;

		private CanvasGroup canvasGroup;

		private Image frontLayerImage;

		private Image backLayerImage;

		private State state;

		private float startMarkTime;

		private float scaleDiff => startScale - endScale;

		public Tuple<float, Color>[] GetUpdatedColorSteps()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			Color item = Utils.Transparentize(((Graphic)backLayerImage).color);
			return new Tuple<float, Color>[8]
			{
				Tuple.Create<float, Color>(0f, Color.white),
				Tuple.Create<float, Color>(0.0333f, Color.black),
				Tuple.Create<float, Color>(0.0667f, Color.white),
				Tuple.Create<float, Color>(0.1333f, Color.black),
				Tuple.Create<float, Color>(0.2f, ((Graphic)backLayerImage).color),
				Tuple.Create<float, Color>(0.4f, item),
				Tuple.Create<float, Color>(0.4667f, ((Graphic)backLayerImage).color),
				Tuple.Create<float, Color>(0.5333f, item)
			};
		}

		private void Awake()
		{
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			frontLayerImage = ((Component)((Component)this).transform.Find("DeathCrossFrontLayer")).gameObject.GetComponent<Image>();
			backLayerImage = ((Component)this).gameObject.GetComponent<Image>();
			((Graphic)backLayerImage).color = ConfigManager.AccentColor.value;
			colorSteps = GetUpdatedColorSteps();
			startScale = ConfigManager.StartScale.value;
			endScale = ConfigManager.EndScale.value;
			scalingDuration = ConfigManager.ScalingDuration.value;
			scalingDelay = ConfigManager.ScalingDelay.value;
			markLifetime = ConfigManager.VisibleDuration.value;
			canvasGroup = ((Component)this).GetComponent<CanvasGroup>();
			canvasGroup.alpha = ConfigManager.CrossMarkOpacity.value;
			if (canvasGroup.alpha < 1f)
			{
				((Graphic)backLayerImage).color = Utils.Transparentize(((Graphic)backLayerImage).color);
			}
		}

		protected override void Start()
		{
			ref RectTransform reference = ref rectTransform;
			Transform transform = ((Component)this).transform;
			reference = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			base.Start();
		}

		private float Curve(float x)
		{
			float num = Math.Clamp(x, 0f, 1f);
			float num2 = 1f - num;
			return 1f - num2 * num2 * num2;
		}

		private void UpdateColor(float elapsedTime)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			int i = 0;
			if (!(elapsedTime < 0f))
			{
				for (; i < colorSteps.Length && elapsedTime >= colorSteps[i].Item1; i++)
				{
				}
				((Graphic)frontLayerImage).color = colorSteps[i - 1].Item2;
			}
		}

		private void SetScale(float newScale)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			((Transform)rectTransform).localScale = new Vector3(newScale, newScale, newScale);
		}

		private void UpdateScale(float percentage)
		{
			float scale = startScale - Curve(percentage) * scaleDiff;
			SetScale(scale);
		}

		protected override void Update()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			if (state == State.Hidden && (startMarkImmediately || (Object)(object)enemy == (Object)null || enemy.health <= 0f))
			{
				state = State.Marking;
				startMarkTime = Time.time;
			}
			if (state != 0)
			{
				float num = Time.time - startMarkTime;
				UpdateColor(num);
				UpdateScale((num - scalingDelay) / scalingDuration);
				base.Update();
				((Transform)rectTransform).position = canvasPoint;
				if (Time.time - startMarkTime >= markLifetime)
				{
					Object.Destroy((Object)(object)((Component)this).gameObject);
				}
			}
		}
	}
	public class EnemyIndicatorController : EnemyTrackingBehavior
	{
		private bool _show;

		private bool _cleanedUp;

		private RectTransform rectTransform;

		private CanvasGroup canvasGroup;

		internal GameObject indicatorObject;

		private Image frontLayerImage;

		private Image backLayerImage;

		private TMP_Text frontLayerText;

		private TMP_Text backLayerText;

		private static readonly string DEFAULT_ICON = "dot_circle";

		private string enemyName = "Enemy";

		private bool enemyCountBelowThreshold => (from e in MonoSingleton<EnemyTracker>.Instance.GetCurrentEnemies()
			where !e.puppet
			select e).Count() <= ConfigManager.TrackerThreshold.value;

		private void SetText(string text)
		{
			if (!((Object)(object)frontLayerText == (Object)null) && !((Object)(object)backLayerText == (Object)null))
			{
				frontLayerText.text = text;
				backLayerText.text = text;
			}
		}

		private void SetAccentColor(Color color)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)frontLayerImage == (Object)null) && !((Object)(object)frontLayerText == (Object)null))
			{
				if (((Object)frontLayerImage.sprite).name != DEFAULT_ICON)
				{
					color = Color.white;
				}
				((Graphic)frontLayerImage).color = color;
				((Graphic)frontLayerText).color = color;
			}
		}

		private void SetBackgroundColor(Color color)
		{
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)backLayerImage == (Object)null) && !((Object)(object)backLayerText == (Object)null))
			{
				((Graphic)backLayerImage).color = color;
				((Graphic)backLayerText).color = color;
			}
		}

		private void SetScale(float scale)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//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)
			if (!((Object)(object)rectTransform == (Object)null))
			{
				((Transform)rectTransform).localScale = new Vector3(scale, scale, scale);
				Rect rect = rectTransform.rect;
				float width = ((Rect)(ref rect)).width;
				rect = rectTransform.rect;
				clampPadding = Math.Max(width, ((Rect)(ref rect)).height);
			}
		}

		private void SetAlpha(float alpha, Tuple<float, float> _ = null)
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)canvasGroup == (Object)null))
			{
				canvasGroup.alpha = alpha;
				if (canvasGroup.alpha < 1f)
				{
					SetBackgroundColor(Utils.Transparentize(((Graphic)backLayerImage).color));
				}
				else
				{
					SetBackgroundColor(Utils.Opacitize(((Graphic)backLayerImage).color));
				}
			}
		}

		private void SetActive(bool active)
		{
			if (!((Object)(object)indicatorObject == (Object)null))
			{
				indicatorObject.SetActive(active);
			}
		}

		private void SetNameActive(bool active)
		{
			if ((Object)(object)frontLayerText != (Object)null)
			{
				((Component)frontLayerText).gameObject.SetActive(active);
			}
			if ((Object)(object)backLayerText != (Object)null)
			{
				((Component)backLayerText).gameObject.SetActive(active);
			}
		}

		private void SetEnemyIcon(bool useSpecificEnemyIcon)
		{
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			string input = ((object)(EnemyType)(ref enemy.enemyType)).ToString();
			string key = DEFAULT_ICON;
			if (useSpecificEnemyIcon)
			{
				string text = input.ToSnakeCase();
				if (Plugin.EnemyIcons.ContainsKey(text))
				{
					key = text;
				}
				else
				{
					switch (enemy.FullName.ToLower())
					{
					case "earthmover mortar":
						text = "centaur_mortar";
						break;
					case "earthmover rocket launcher":
						text = "centaur_rocket";
						break;
					case "earthmover tower":
						text = "centaur_orb";
						break;
					case "cancerous rodent":
						text = "cancerous_rodent";
						break;
					case "very cancerous rodent":
						text = "very_cancerous_rodent";
						break;
					case "big johninator":
						text = "big_johninator";
						break;
					}
					if (Plugin.EnemyIcons.ContainsKey(text))
					{
						key = text;
					}
				}
			}
			if (Plugin.EnemyIcons.TryGetValue(key, out Sprite value))
			{
				frontLayerImage.sprite = value;
				backLayerImage.sprite = value;
				SetAccentColor(ConfigManager.TrackerColor.value);
			}
		}

		private void UpdateAppearance()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)indicatorObject == (Object)null))
			{
				SetAccentColor(ConfigManager.TrackerColor.value);
				SetScale(ConfigManager.TrackerScale.value);
				SetAlpha(ConfigManager.TrackerMarkOpacity.value);
				SetNameActive(ConfigManager.TrackerShowEnemyNames.value);
				SetEnemyIcon(ConfigManager.TrackerUseSpecificEnemyIcons.value);
				indicatorObject.SetActive(ConfigManager.EnableTrackers.value);
			}
		}

		private void UpdateShow()
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			if (!enemyCountBelowThreshold && !ConfigManager.IsEnemyForceTracked(enemy.enemyType))
			{
				_show = false;
				if ((Object)(object)indicatorObject != (Object)null)
				{
					indicatorObject.SetActive(false);
				}
				return;
			}
			if ((Object)(object)indicatorObject == (Object)null)
			{
				indicatorObject = Object.Instantiate<GameObject>(Plugin.EnemyIndicatorPrefab, Plugin.CrossoverCanvas.transform);
				rectTransform = indicatorObject.GetComponent<RectTransform>();
				canvasGroup = indicatorObject.GetComponent<CanvasGroup>();
				frontLayerImage = ((Component)indicatorObject.transform.Find("EnemyTrackerFrontLayer")).GetComponent<Image>();
				backLayerImage = indicatorObject.GetComponent<Image>();
				frontLayerText = ((Component)indicatorObject.transform.Find("EnemyTrackerFrontLayer/FrontEnemyName")).GetComponent<TMP_Text>();
				backLayerText = ((Component)indicatorObject.transform.Find("EnemyName")).GetComponent<TMP_Text>();
			}
			SetText(enemyName);
			UpdateAppearance();
			_show = true;
		}

		private void HookStuff()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Expected O, but got Unknown
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Expected O, but got Unknown
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Expected O, but got Unknown
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			ConfigManager.EnableTrackers.postValueChangeEvent += new PostBoolValueChangeEvent(SetActive);
			ConfigManager.TrackerUseSpecificEnemyIcons.postValueChangeEvent += new PostBoolValueChangeEvent(SetEnemyIcon);
			ConfigManager.TrackerShowEnemyNames.postValueChangeEvent += new PostBoolValueChangeEvent(SetNameActive);
			ConfigManager.TrackerColor.postValueChangeEvent += new PostColorValueChangeEvent(SetAccentColor);
			ConfigManager.TrackerScale.postValueChangeEvent += new PostFloatValueChangeEvent(SetScale);
			ConfigManager.TrackerMarkOpacity.postValueChangeEvent += new PostFloatSliderValueChangeEvent(SetAlpha);
			EnemyListener.EnemyCountChanged += UpdateShow;
			enemy.destroyOnDeath.Add(indicatorObject);
		}

		private void UnhookStuff()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected O, but got Unknown
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Expected O, but got Unknown
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Expected O, but got Unknown
			EnemyListener.EnemyCountChanged -= UpdateShow;
			ConfigManager.EnableTrackers.postValueChangeEvent -= new PostBoolValueChangeEvent(SetActive);
			ConfigManager.TrackerUseSpecificEnemyIcons.postValueChangeEvent -= new PostBoolValueChangeEvent(SetEnemyIcon);
			ConfigManager.TrackerShowEnemyNames.postValueChangeEvent -= new PostBoolValueChangeEvent(SetNameActive);
			ConfigManager.TrackerColor.postValueChangeEvent -= new PostColorValueChangeEvent(SetAccentColor);
			ConfigManager.TrackerScale.postValueChangeEvent -= new PostFloatValueChangeEvent(SetScale);
			ConfigManager.TrackerMarkOpacity.postValueChangeEvent -= new PostFloatSliderValueChangeEvent(SetAlpha);
		}

		private void Awake()
		{
			clampToScreen = true;
		}

		protected override void Start()
		{
			base.Start();
			TextInfo textInfo = CultureInfo.CurrentCulture.TextInfo;
			EnemyIdentifier obj = enemy;
			enemyName = textInfo.ToTitleCase(((obj != null) ? obj.FullName.ToLower() : null) ?? "Enemy");
			UpdateShow();
			HookStuff();
		}

		internal void PrintDebugInfo()
		{
			//IL_004c: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			EnemyIdentifier obj = enemy;
			string text = ((obj != null) ? ((object)((Component)obj).transform).ToString() : null) ?? "NULL TRANSFORM";
			EnemyIdentifier obj2 = enemy;
			Vector3? obj3;
			if (obj2 == null)
			{
				obj3 = null;
			}
			else
			{
				Transform transform = ((Component)obj2).transform;
				obj3 = ((transform != null) ? new Vector3?(transform.position) : null);
			}
			Vector3 val = (Vector3)(((??)obj3) ?? (Vector3.one * -1f));
			string text2 = ((object)(Vector3)(ref val)).ToString() ?? "";
			string text3 = $"{enemy?.health ?? (-1f)}";
			GameObject obj4 = indicatorObject;
			object obj5;
			if (obj4 == null)
			{
				obj5 = null;
			}
			else
			{
				val = obj4.transform.position;
				obj5 = ((object)(Vector3)(ref val)).ToString();
			}
			if (obj5 == null)
			{
				obj5 = "NULL POS";
			}
			string text4 = (string)obj5;
			Plugin.Log.LogInfo((object)$"--- Enemy {enemyName} | transform: {text} | pos: {text2} | hp: {text3} | indicatorObject: {indicatorObject} | indicatorObjPos: {text4}");
		}

		protected override void Update()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)enemy == (Object)null || enemy.health <= 0f || (Object)(object)((Component)enemy).transform == (Object)null)
			{
				RemoveIndicatorAndStop();
			}
			else if (_show)
			{
				base.Update();
				((Transform)rectTransform).position = canvasPoint;
			}
		}

		private void RemoveIndicatorAndStop()
		{
			if (!_cleanedUp)
			{
				_cleanedUp = true;
				_show = false;
				if ((Object)(object)indicatorObject != (Object)null)
				{
					Object.Destroy((Object)(object)indicatorObject);
				}
				UnhookStuff();
				Object.Destroy((Object)(object)this);
			}
		}

		private void OnDestroy()
		{
			UnhookStuff();
			if ((Object)(object)indicatorObject != (Object)null)
			{
				Object.Destroy((Object)(object)indicatorObject);
			}
		}
	}
	public static class EnemyListener
	{
		public delegate void OnSomeEnemyDied();

		public static event OnSomeEnemyDied EnemyCountChanged;

		internal static void NotifyChange()
		{
			EnemyListener.EnemyCountChanged?.Invoke();
		}
	}
	public class EnemyTrackingBehavior : MonoBehaviour
	{
		public Vector3 canvasPoint;

		protected Vector3 lastEnemyPosition = Vector3.zero;

		public EnemyIdentifier enemy;

		protected float enemyHeight;

		public bool clampToScreen;

		public float clampPadding;

		public void SetEnemy(EnemyIdentifier enemy)
		{
			this.enemy = enemy;
		}

		protected Vector3 GetEnemyPosition()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)enemy != (Object)null && (Object)(object)((Component)enemy).transform != (Object)null)
			{
				lastEnemyPosition = ((Component)enemy).transform.position;
			}
			return lastEnemyPosition + enemyHeight / 2f * Vector3.up;
		}

		private void UpdateCanvasPoint()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = MonoSingleton<CameraController>.Instance.cam.WorldToScreenPoint(GetEnemyPosition());
			bool num = val.z < 0f;
			int privateField = MonoSingleton<PostProcessV2_Handler>.Instance.GetPrivateField<int>("width");
			int privateField2 = MonoSingleton<PostProcessV2_Handler>.Instance.GetPrivateField<int>("height");
			val.x *= Screen.width;
			val.y *= Screen.height;
			val.x /= privateField;
			val.y /= privateField2;
			if (num)
			{
				float num2 = (float)privateField / 2f;
				float num3 = (float)privateField - val.x - num2;
				if (Mathf.Approximately(num3, 0f))
				{
					num3 = -1f;
				}
				val.x = num2 + num3 * 100000f;
			}
			if (clampToScreen)
			{
				val.x = Mathf.Clamp(val.x, clampPadding, (float)privateField - clampPadding);
				val.y = Mathf.Clamp(val.y, clampPadding, (float)privateField2 - clampPadding);
			}
			canvasPoint = val;
		}

		protected virtual void Start()
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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)
			if (!((Object)(object)enemy == (Object)null))
			{
				Collider component = ((Component)enemy).GetComponent<Collider>();
				Bounds bounds = component.bounds;
				float y = (((Bounds)(ref bounds)).center - ((Component)enemy).transform.position).y;
				bounds = component.bounds;
				enemyHeight = y + ((Bounds)(ref bounds)).extents.y;
			}
		}

		protected virtual void Update()
		{
			UpdateCanvasPoint();
		}
	}
	[BepInPlugin("com.github.end-4.crossover", "Crossover", "1.1.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource? Log;

		public static string workingPath = Assembly.GetExecutingAssembly().Location;

		public static string workingDir = Path.GetDirectoryName(workingPath);

		public const string PluginGUID = "com.github.end-4.crossover";

		public const string PluginName = "Crossover";

		public const string PluginVersion = "1.1.1";

		internal static GameObject DeathCrossPrefab;

		internal static GameObject EnemyIndicatorPrefab;

		internal static GameObject CrossoverCanvasPrefab;

		internal static GameObject CrossoverCanvas;

		internal static Dictionary<string, Sprite> EnemyIcons = new Dictionary<string, Sprite>();

		private static readonly string BundlePath = Path.Combine(workingDir, "assets", "crossover.bundle");

		internal static string[] IconNames = new string[41]
		{
			"dot_circle", "big_johninator", "cancerous_rodent", "centaur_mortar", "centaur_orb", "centaur_rocket", "cerberus", "deathcatcher", "drone", "ferryman",
			"filth", "flesh_panopticon", "flesh_prison", "gabriel", "gabriel_second", "gutterman", "guttertank", "hideous_mass", "idol", "malicious_face",
			"mandalore", "mindflayer", "minos_prime", "minotaur", "mirror_reaper", "power", "providence", "puppet", "schism", "sisyphus",
			"sisyphus_prime", "soldier", "stalker", "stray", "mannequin", "streetcleaner", "swordsmachine", "turret", "v2", "very_cancerous_rodent",
			"virtue"
		};

		private void LoadObjects()
		{
			AssetBundle val = AssetBundle.LoadFromFile(BundlePath);
			if ((Object)(object)val == (Object)null)
			{
				Log.LogError((object)"Couldn't load asset bundle");
			}
			DeathCrossPrefab = val.LoadAsset<GameObject>("DeathCross");
			EnemyIndicatorPrefab = val.LoadAsset<GameObject>("EnemyIndicator");
			CrossoverCanvasPrefab = val.LoadAsset<GameObject>("CrossoverCanvas");
			CrossoverCanvas = Object.Instantiate<GameObject>(CrossoverCanvasPrefab);
			Object.DontDestroyOnLoad((Object)(object)CrossoverCanvas);
			((Object)CrossoverCanvas).hideFlags = (HideFlags)61;
			for (int i = 0; i < IconNames.Length; i++)
			{
				string text = IconNames[i];
				Sprite value = val.LoadAsset<Sprite>(text);
				EnemyIcons.Add(text, value);
			}
		}

		private void Awake()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			ConfigManager.Initialize();
			LoadObjects();
			new Harmony("Crossover").PatchAll();
			UserHints.Initialize();
			Log.LogInfo((object)"Crossover loaded!");
		}
	}
	public static class UserHints
	{
		public static void IssueUpdateNoticeIfNecessary()
		{
			Version value = new Version(ConfigManager.LastVersion.value);
			if (new Version("1.1.0").CompareTo(value) == 1)
			{
				ConfigManager.LastVersion.value = "1.1.1";
				NotificationSystem.NotifySend("<color=#db1e39>Crossover</color> updated", "<b>1.1.0</b>: Added enemy tracking icons. Great for hunting down the last Cyber Grind Schisms or focusing on dangerous enemies. You can enable it in <color=#55c7f6>Options > Plugin Config > Crossover</color>", (Sprite)null, Path.Combine(Plugin.workingDir, "icon.png"), (Urgency)1, "NotifySend", 0u, (Dictionary<string, string>)null, 10000);
			}
			SceneManager.sceneLoaded -= IssueUpdateNoticeIfNecessary;
		}

		public static void IssueUpdateNoticeIfNecessary(Scene _, LoadSceneMode __)
		{
			IssueUpdateNoticeIfNecessary();
		}

		public static void Initialize()
		{
		}

		static UserHints()
		{
			SceneManager.sceneLoaded += IssueUpdateNoticeIfNecessary;
		}
	}
	internal static class Utils
	{
		internal static T GetPrivateField<T>(this object obj, string field)
		{
			Type type = obj.GetType();
			if (type.GetField(field, BindingFlags.Instance | BindingFlags.NonPublic) == null)
			{
				throw new ArgumentException("The field " + field + " does not exist in target class " + type.Name + "!");
			}
			return (T)type.GetField(field, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(obj);
		}

		internal static Color Transparentize(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			return new Color(color.r, color.g, color.b, 0f);
		}

		internal static Color Opacitize(Color color)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			return new Color(color.r, color.g, color.b, 1f);
		}

		internal static string ToSnakeCase(this string input)
		{
			if (string.IsNullOrEmpty(input))
			{
				return input;
			}
			return Regex.Replace(input, "(?<!^)(?=[A-Z][a-z])|(?<=[a-z0-9])(?=[A-Z])", "_").ToLowerInvariant();
		}
	}
}
namespace Crossover.Patches
{
	[HarmonyPatch(typeof(EnemyIdentifier))]
	internal class EnemyPatch
	{
		[HarmonyPostfix]
		[HarmonyPatch("ProcessDeath")]
		private static void EnemyDied(EnemyIdentifier __instance)
		{
			if (ConfigManager.Enable.value && !(__instance.health < ConfigManager.EnemyHealthThreshold.value))
			{
				GameObject obj = Object.Instantiate<GameObject>(Plugin.DeathCrossPrefab, Plugin.CrossoverCanvas.transform);
				obj.AddComponent<CrossBehavior>().SetEnemy(__instance);
				obj.SetActive(true);
				EnemyListener.NotifyChange();
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("Start")]
		private static void EnemySpawned(EnemyIdentifier __instance)
		{
			if (ConfigManager.EnableTrackers.value && (!__instance.puppet || !ConfigManager.TrackerIgnorePuppets.value) && !((Object)(object)((Component)__instance).gameObject.GetComponent<EnemyIndicatorController>() != (Object)null))
			{
				((Component)__instance).gameObject.AddComponent<EnemyIndicatorController>().SetEnemy(__instance);
				EnemyListener.NotifyChange();
			}
		}
	}
}