Decompiled source of ScannableSpikes v1.0.0

ScannableSpikes.dll

Decompiled 2 years ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CSync.Extensions;
using CSync.Lib;
using HarmonyLib;
using SlammerRebalance.ConfigSync;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6", FrameworkDisplayName = ".NET Framework 4.6")]
[assembly: AssemblyCompany("ScannableSpikes")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ScannableSpikes")]
[assembly: AssemblyTitle("ScannableSpikes")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace SlammerRebalance
{
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInPlugin("me.excuze.lethal.scannablespikes", "ScannableSpikes", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		internal static ScannableSpikesConfig Config;

		private void Awake()
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			Logger = ((BaseUnityPlugin)this).Logger;
			Config = new ScannableSpikesConfig(((BaseUnityPlugin)this).Config);
			Logger.LogInfo((object)"About to patch!");
			new Harmony("me.excuze.lethal.scannablespikes").PatchAll();
			try
			{
				SpikeRoofTrapPatch.GetNearEntranceMethod = typeof(SpikeRoofTrap).GetMethod("GetNearEntrance", BindingFlags.Instance | BindingFlags.NonPublic);
			}
			catch (Exception ex)
			{
				SpikeRoofTrapPatch.GetNearEntranceMethod = null;
				Logger.LogError((object)ex);
				Logger.LogError((object)"Error fetching necessary methods for chance modification, this feature will not work. Is the game currently an unsupported version?");
				return;
			}
			Logger.LogInfo((object)"Plugin ScannableSpikes is loaded!");
		}
	}
	[HarmonyPatch]
	public class SpikeRoofTrapPatch
	{
		public static MethodInfo GetNearEntranceMethod;

		[HarmonyPatch(typeof(SpikeRoofTrap), "SlamSpikeTrapSequence")]
		[HarmonyPostfix]
		public static IEnumerator SpikeSlamSequence(IEnumerator __result, bool ___slamOnIntervals)
		{
			if (!___slamOnIntervals)
			{
				yield return (object)new WaitForSeconds(Plugin.Config.AdditionalSlamDelay.Value);
			}
			while (__result.MoveNext())
			{
				yield return __result.Current;
			}
		}

		private static void DisableSpikeTrap(SpikeRoofTrap instance)
		{
			instance.trapActive = false;
			Transform parent = ((Component)instance).gameObject.transform.parent;
			if (!((Object)(object)parent != (Object)null))
			{
				return;
			}
			Transform parent2 = parent.parent;
			if ((Object)(object)parent2 != (Object)null)
			{
				Transform parent3 = parent2.parent;
				if ((Object)(object)parent3 != (Object)null)
				{
					((Component)parent3).gameObject.SetActive(false);
				}
			}
		}

		private static void TryModifyTypeChances(SpikeRoofTrap instance, ref bool ___slamOnIntervals, ref float ___slamInterval, ref bool ___nearEntrance)
		{
			//IL_0021: 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)
			if (GetNearEntranceMethod == null)
			{
				return;
			}
			Random random = new Random(StartOfRound.Instance.randomMapSeed + 30 + (int)((Component)instance).transform.position.x + (int)((Component)instance).transform.position.z);
			object obj = null;
			try
			{
				obj = GetNearEntranceMethod.Invoke(instance, null);
			}
			catch (Exception ex)
			{
				Plugin.Logger.LogError((object)ex);
				Plugin.Logger.LogError((object)"Error while performing chance modification, this feature will not work. Is the game currently an unsupported version?");
			}
			if (obj == null)
			{
				return;
			}
			bool flag = (bool)obj;
			if (random.NextDouble() < (double)Plugin.Config.IntervalSlamTypeChance.Value || flag)
			{
				___slamOnIntervals = true;
				int num = random.Next(0, 100);
				if (num < 10)
				{
					___slamInterval = (float)(random.NextDouble() * (double)(Plugin.Config.LongIntervalMaximum.Value - Plugin.Config.LongIntervalMinimum.Value) + (double)Plugin.Config.LongIntervalMinimum.Value);
				}
				else if (num > 90)
				{
					___slamInterval = (float)(random.NextDouble() * (double)(Plugin.Config.ShortIntervalMaximum.Value - Plugin.Config.ShortIntervalMinimum.Value) + (double)Plugin.Config.ShortIntervalMinimum.Value);
				}
				else
				{
					___slamInterval = (float)(random.NextDouble() * (double)(Plugin.Config.NormalIntervalMaximum.Value - Plugin.Config.NormalIntervalMinimum.Value) + (double)Plugin.Config.NormalIntervalMinimum.Value);
				}
				if (___nearEntrance)
				{
					___slamInterval = Mathf.Max(___slamInterval, 1.25f);
				}
			}
		}

		[HarmonyPatch(typeof(SpikeRoofTrap), "Update")]
		[HarmonyPrefix]
		private static bool SpikeUpdate()
		{
			if (Plugin.Config.DisableTraps.Value)
			{
				return false;
			}
			return true;
		}

		[HarmonyPatch(typeof(SpikeRoofTrap), "Start")]
		[HarmonyPostfix]
		private static void SpikeStart(SpikeRoofTrap __instance, ref bool ___slamOnIntervals, ref float ___slamInterval, ref bool ___nearEntrance)
		{
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			if (Plugin.Config.DisableTraps.Value)
			{
				DisableSpikeTrap(__instance);
				return;
			}
			TryModifyTypeChances(__instance, ref ___slamOnIntervals, ref ___slamInterval, ref ___nearEntrance);
			GameObject obj = CreateScanNode(0, Plugin.Config.MaxTrapScanRange.Value, 1, "Spikes", (!Plugin.Config.IndicateTrapTypeOnScan.Value) ? "" : (___slamOnIntervals ? "Slams on interval" : "Slams on players"));
			obj.transform.SetParent(((Component)__instance).gameObject.transform, false);
			obj.transform.localPosition = new Vector3(0f, -1.5f, 0f);
		}

		private static GameObject CreateScanNode(int minRange, int maxRange, int type, string headerText, string subText = "")
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			GameObject val = new GameObject("ScanNode");
			ScanNodeProperties obj = val.AddComponent<ScanNodeProperties>();
			obj.minRange = minRange;
			obj.maxRange = maxRange;
			obj.creatureScanID = -1;
			obj.nodeType = type;
			obj.headerText = headerText;
			obj.subText = subText;
			val.AddComponent<BoxCollider>();
			val.layer = 22;
			return val;
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "ScannableSpikes";

		public const string PLUGIN_NAME = "ScannableSpikes";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace SlammerRebalance.ConfigSync
{
	internal class ScannableSpikesConfig : SyncedConfig2<ScannableSpikesConfig>
	{
		[DataMember]
		public readonly SyncedEntry<bool> DisableTraps;

		public readonly SyncedEntry<int> MaxTrapScanRange;

		public readonly SyncedEntry<bool> IndicateTrapTypeOnScan;

		public readonly SyncedEntry<bool> EnableScanNode;

		[DataMember]
		public readonly SyncedEntry<float> AdditionalSlamDelay;

		[DataMember]
		public readonly SyncedEntry<float> IntervalSlamTypeChance;

		[DataMember]
		public readonly SyncedEntry<float> LongIntervalMinimum;

		[DataMember]
		public readonly SyncedEntry<float> LongIntervalMaximum;

		[DataMember]
		public readonly SyncedEntry<float> NormalIntervalMinimum;

		[DataMember]
		public readonly SyncedEntry<float> NormalIntervalMaximum;

		[DataMember]
		public readonly SyncedEntry<float> ShortIntervalMinimum;

		[DataMember]
		public readonly SyncedEntry<float> ShortIntervalMaximum;

		public ScannableSpikesConfig(ConfigFile cfg)
			: base("me.excuze.lethal.scannablespikes")
		{
			cfg.SaveOnConfigSet = false;
			ConfigManager.Register<ScannableSpikesConfig>((SyncedConfig2<ScannableSpikesConfig>)this);
			DisableTraps = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, "General", "DisableSpikeTraps", false, "Fully disables and gets rid of spike traps, in all their forms. If you want to get rid of a specific type, look at the IntervalSlamTypeChance option");
			AdditionalSlamDelay = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, "General", "AdditionalSlamDelay", 0f, "Requires spike traps being enabled. How long, in seconds, player-activated traps will wait to slam after a player is detected");
			IntervalSlamTypeChance = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, "General", "IntervalSlamTypeChance", 0.8f, "Requires spike traps being enabled. 0.0-1.0. 0 = 0%, 1 = 100%. The chance for any spawned traps to be interval-based rather than player-detecting. Set to 1 to disable player-detecting traps, or 0 to disable interval traps (except near the entrance)");
			EnableScanNode = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, "Scanning", "EnableTrapScanNode", true, "If true, you will be able to right-click-scan for traps like you can for Snare Fleas");
			MaxTrapScanRange = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, "Scanning", "MaxTrapScanRange", 14, "Requires trap scan nodes being enabled. How far away you can begin to right-click-scan spike traps from");
			IndicateTrapTypeOnScan = SyncedBindingExtensions.BindSyncedEntry<bool>(cfg, "Scanning", "IndicateTrapTypeOnScan", false, "Requires trap scan nodes being enabled. If true, the scan node will show whether the trap operates on an interval or is player-activated");
			LongIntervalMinimum = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, "Timings", "LongIntervalMinimumTime", 0.77f, "Requires spike traps being enabled. ~10% of traps will have 'long' intervals, and this assigns the shortest interval that type can slam on, in seconds.");
			LongIntervalMaximum = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, "Timings", "LongIntervalMaximumTime", 27f, "Requires spike traps being enabled. ~10% of traps will have 'long' intervals, and this assigns the greatest interval that type can slam on, in seconds.");
			NormalIntervalMinimum = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, "Timings", "NormalIntervalMinimumTime", 0.77f, "Requires spike traps being enabled. ~80% of traps will have 'normal' intervals, and this assigns the shortest interval that type can slam on, in seconds.");
			NormalIntervalMaximum = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, "Timings", "NormalIntervalMaximumTime", 11.5f, "Requires spike traps being enabled. ~80% of traps will have 'normal' intervals, and this assigns the greatest interval that type can slam on, in seconds.");
			ShortIntervalMinimum = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, "Timings", "ShortIntervalMinimumTime", 0.71f, "Requires spike traps being enabled. ~10% of traps will have 'short' intervals, and this assigns the shortest interval that type can slam on, in seconds.");
			ShortIntervalMaximum = SyncedBindingExtensions.BindSyncedEntry<float>(cfg, "Timings", "ShortIntervalMaximumTime", 2.9f, "Requires spike traps being enabled. ~10% of traps will have 'short' intervals, and this assigns the greatest interval that type can slam on, in seconds.");
			ClearOrphanedEntries(cfg);
			cfg.Save();
			cfg.SaveOnConfigSet = true;
		}

		private static void ClearOrphanedEntries(ConfigFile cfg)
		{
			((Dictionary<ConfigDefinition, string>)AccessTools.Property(typeof(ConfigFile), "OrphanedEntries").GetValue(cfg)).Clear();
		}
	}
}