Decompiled source of ScannableFireExit v1.0.0

ScannableFireExit.dll

Decompiled 7 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using LethalModDataLib.Attributes;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TestAccount666.ScannableFireExit")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("The company found some extra money in the recently fired executive's desk and decided to add Scan Nodes to Fire Exits")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+1602703167ecdc7021d314125d875582ebc92c91")]
[assembly: AssemblyProduct("ScannableFireExit")]
[assembly: AssemblyTitle("TestAccount666.ScannableFireExit")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.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.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 ScannableFireExit
{
	public static class FireExitData
	{
		[ModData(/*Could not decode attribute arguments.*/)]
		internal static readonly Dictionary<string, List<int>> LevelFireExitDictionary = new Dictionary<string, List<int>>();
	}
	[BepInPlugin("TestAccount666.ScannableFireExit", "ScannableFireExit", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ScannableFireExit : BaseUnityPlugin
	{
		internal static ConfigEntry<bool> onlySeenFireExits;

		public static ScannableFireExit Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		private void Awake()
		{
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			Patch();
			onlySeenFireExits = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "1. Only seen fire exits", false, "If true, will only allow you to scan fire exits you've used");
			Logger.LogInfo((object)"TestAccount666.ScannableFireExit v1.0.0 has loaded!");
		}

		internal static void Patch()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Expected O, but got Unknown
			if (Harmony == null)
			{
				Harmony = new Harmony("TestAccount666.ScannableFireExit");
			}
			Logger.LogDebug((object)"Patching...");
			Harmony.PatchAll();
			Logger.LogDebug((object)"Finished patching!");
		}

		internal static void Unpatch()
		{
			Logger.LogDebug((object)"Unpatching...");
			Harmony? harmony = Harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
			Logger.LogDebug((object)"Finished unpatching!");
		}
	}
	public class ScanNodeContainer : MonoBehaviour
	{
		public GameObject? scanNodeGameObject;

		public ScanNodeProperties? scanNode;
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "TestAccount666.ScannableFireExit";

		public const string PLUGIN_NAME = "ScannableFireExit";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace ScannableFireExit.Patches
{
	[HarmonyPatch(typeof(EntranceTeleport))]
	public static class FireExitPatch
	{
		[HarmonyPatch("Awake")]
		[HarmonyPostfix]
		public static void AfterAwake(EntranceTeleport __instance)
		{
			if (__instance.isEntranceToBuilding && __instance.entranceId != 0)
			{
				HandleFireExit(__instance);
			}
		}

		[HarmonyPatch("TeleportPlayer")]
		[HarmonyPostfix]
		public static void AfterEnterOrExit(EntranceTeleport __instance)
		{
			FindFireExitEntrance(__instance, out EntranceTeleport entrance);
			if (entrance != null)
			{
				MarkFireExitAsFound(entrance);
				HandleFireExit(entrance);
			}
		}

		private static void MarkFireExitAsFound(EntranceTeleport fireExit)
		{
			string currentLevelName = GetCurrentLevelName();
			List<int> orCreateFireExitsForLevel = GetOrCreateFireExitsForLevel(currentLevelName);
			if (!orCreateFireExitsForLevel.Contains(fireExit.entranceId))
			{
				orCreateFireExitsForLevel.Add(fireExit.entranceId);
			}
		}

		private static void HandleFireExit(EntranceTeleport entranceTeleport)
		{
			EntranceTeleport entranceTeleport2 = entranceTeleport;
			if (((Component)entranceTeleport2).GetComponent<ScanNodeContainer>() == null)
			{
				string currentLevelName = GetCurrentLevelName();
				List<int> orCreateFireExitsForLevel = GetOrCreateFireExitsForLevel(currentLevelName);
				if (orCreateFireExitsForLevel.Any((int otherFireExit) => entranceTeleport2.entranceId == otherFireExit) || !OnlyWhenSeen())
				{
					CreateScanNodeOnObject(((Component)entranceTeleport2).gameObject, "Fire Exit", $"Emergency Exit #{entranceTeleport2.entranceId}");
				}
			}
		}

		private static void FindFireExitEntrance(EntranceTeleport entranceTeleport, out EntranceTeleport? entrance)
		{
			EntranceTeleport entranceTeleport2 = entranceTeleport;
			entrance = null;
			if (entranceTeleport2.entranceId == 0)
			{
				return;
			}
			if (entranceTeleport2.isEntranceToBuilding)
			{
				entrance = entranceTeleport2;
				return;
			}
			EntranceTeleport[] source = Object.FindObjectsOfType<EntranceTeleport>();
			entrance = ((IEnumerable<EntranceTeleport>)source).FirstOrDefault((Func<EntranceTeleport, bool>)((EntranceTeleport allEntranceTeleport) => allEntranceTeleport.isEntranceToBuilding && allEntranceTeleport.entranceId == entranceTeleport2.entranceId));
		}

		private static bool OnlyWhenSeen()
		{
			return ScannableFireExit.onlySeenFireExits.Value;
		}

		private static string GetCurrentLevelName()
		{
			return RoundManager.Instance.currentLevel.PlanetName;
		}

		private static List<int> GetOrCreateFireExitsForLevel(string levelName)
		{
			if (FireExitData.LevelFireExitDictionary.TryGetValue(levelName, out List<int> value))
			{
				return value;
			}
			value = new List<int>();
			FireExitData.LevelFireExitDictionary[levelName] = value;
			return value;
		}

		private static void CreateScanNodeOnObject(GameObject gameObject, string headerText, string? subText)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Expected O, but got Unknown
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("ScanNode", new Type[2]
			{
				typeof(ScanNodeProperties),
				typeof(BoxCollider)
			})
			{
				layer = LayerMask.NameToLayer("ScanNode")
			};
			val.transform.localScale = Vector3.one * 1f;
			val.transform.parent = gameObject.transform;
			GameObject val2 = val;
			val2.transform.SetLocalPositionAndRotation(Vector3.zero, Quaternion.identity);
			ScanNodeProperties component = val2.GetComponent<ScanNodeProperties>();
			component.scrapValue = 0;
			component.creatureScanID = -1;
			component.nodeType = 0;
			component.minRange = 12;
			component.maxRange = 52;
			component.requiresLineOfSight = false;
			component.headerText = headerText;
			if (subText != null)
			{
				component.subText = subText;
			}
			ScanNodeContainer scanNodeContainer = gameObject.AddComponent<ScanNodeContainer>();
			scanNodeContainer.scanNodeGameObject = val2;
			scanNodeContainer.scanNode = component;
		}
	}
}