Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ScannableSpikes v1.0.0
ScannableSpikes.dll
Decompiled 2 years agousing 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(); } } }