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 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(); 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, "-- DEATH CROSSES --", 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, "-- ENEMY TRACKERS --", 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, "-- ADVANCED --", 22); new ConfigHeader(config.rootPanel, "// Death crosses", 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(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, "// Enemy trackers", 16, (TextAlignmentOptions)513); TrackerScale = new FloatField(config.rootPanel, "Tracker mark scale", "trackerScale", 1f); TrackerMarkOpacity = new FloatSliderField(config.rootPanel, "Tracker mark opacity", "trackerMarkOpacity", new Tuple(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[] colorSteps = Array.Empty>(); 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[] 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[8] { Tuple.Create(0f, Color.white), Tuple.Create(0.0333f, Color.black), Tuple.Create(0.0667f, Color.white), Tuple.Create(0.1333f, Color.black), Tuple.Create(0.2f, ((Graphic)backLayerImage).color), Tuple.Create(0.4f, item), Tuple.Create(0.4667f, ((Graphic)backLayerImage).color), Tuple.Create(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(); backLayerImage = ((Component)this).gameObject.GetComponent(); ((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.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.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 _ = 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(Plugin.EnemyIndicatorPrefab, Plugin.CrossoverCanvas.transform); rectTransform = indicatorObject.GetComponent(); canvasGroup = indicatorObject.GetComponent(); frontLayerImage = ((Component)indicatorObject.transform.Find("EnemyTrackerFrontLayer")).GetComponent(); backLayerImage = indicatorObject.GetComponent(); frontLayerText = ((Component)indicatorObject.transform.Find("EnemyTrackerFrontLayer/FrontEnemyName")).GetComponent(); backLayerText = ((Component)indicatorObject.transform.Find("EnemyName")).GetComponent(); } 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.Instance.cam.WorldToScreenPoint(GetEnemyPosition()); bool num = val.z < 0f; int privateField = MonoSingleton.Instance.GetPrivateField("width"); int privateField2 = MonoSingleton.Instance.GetPrivateField("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(); 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 EnemyIcons = new Dictionary(); 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("DeathCross"); EnemyIndicatorPrefab = val.LoadAsset("EnemyIndicator"); CrossoverCanvasPrefab = val.LoadAsset("CrossoverCanvas"); CrossoverCanvas = Object.Instantiate(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(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("Crossover updated", "1.1.0: Added enemy tracking icons. Great for hunting down the last Cyber Grind Schisms or focusing on dangerous enemies. You can enable it in Options > Plugin Config > Crossover", (Sprite)null, Path.Combine(Plugin.workingDir, "icon.png"), (Urgency)1, "NotifySend", 0u, (Dictionary)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(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, "(?(Plugin.DeathCrossPrefab, Plugin.CrossoverCanvas.transform); obj.AddComponent().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() != (Object)null)) { ((Component)__instance).gameObject.AddComponent().SetEnemy(__instance); EnemyListener.NotifyChange(); } } } }