using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; 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("RendNutcrackerApocalypse")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Rend Nutcracker Apocalypse Mod")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("RendNutcrackerApocalypse")] [assembly: AssemblyTitle("RendNutcrackerApocalypse")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace RendNutcrackerApocalypse; [BepInPlugin("com.antigravity.rendnutcrackerapocalypse", "RendNutcrackerApocalypse", "1.0.0")] public class Plugin : BaseUnityPlugin { private const string ModGUID = "com.antigravity.rendnutcrackerapocalypse"; private const string ModName = "RendNutcrackerApocalypse"; private const string ModVersion = "1.0.0"; private readonly Harmony harmony = new Harmony("com.antigravity.rendnutcrackerapocalypse"); private static Plugin Instance; public static ConfigEntry ConfigApocalypseChance; public static ConfigEntry ConfigForceApocalypse; public static ConfigEntry ConfigInstantSpawn; public static bool IsNutcrackerApocalypseActive; private void Awake() { if ((Object)(object)Instance == (Object)null) { Instance = this; } ConfigApocalypseChance = ((BaseUnityPlugin)this).Config.Bind("General", "ApocalypseChance", 1f, "The percentage chance (0.0 to 100.0) of the Nutcracker Apocalypse happening on Rend (or maps containing 'antigravity')."); ConfigForceApocalypse = ((BaseUnityPlugin)this).Config.Bind("Debug", "ForceApocalypse", false, "If set to true, the Nutcracker Apocalypse will ALWAYS trigger on Rend/antigravity maps (for testing)."); ConfigInstantSpawn = ((BaseUnityPlugin)this).Config.Bind("General", "InstantSpawn", true, "If true, Nutcrackers will spawn instantly from vents as soon as they are scheduled, making the apocalypse start much faster."); harmony.PatchAll(typeof(Patches)); } } [HarmonyPatch] public static class Patches { private static EnemyType FindNutcrackerEnemyType() { if ((Object)(object)StartOfRound.Instance != (Object)null && StartOfRound.Instance.levels != null) { SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { if ((Object)(object)val == (Object)null) { continue; } foreach (SpawnableEnemyWithRarity enemy in val.Enemies) { if ((Object)(object)enemy?.enemyType != (Object)null && enemy.enemyType.enemyName.ToLower().Contains("nutcracker")) { return enemy.enemyType; } } foreach (SpawnableEnemyWithRarity outsideEnemy in val.OutsideEnemies) { if ((Object)(object)outsideEnemy?.enemyType != (Object)null && outsideEnemy.enemyType.enemyName.ToLower().Contains("nutcracker")) { return outsideEnemy.enemyType; } } foreach (SpawnableEnemyWithRarity daytimeEnemy in val.DaytimeEnemies) { if ((Object)(object)daytimeEnemy?.enemyType != (Object)null && daytimeEnemy.enemyType.enemyName.ToLower().Contains("nutcracker")) { return daytimeEnemy.enemyType; } } } } return null; } [HarmonyPatch(typeof(RoundManager), "LoadNewLevel")] [HarmonyPrefix] public static void LoadNewLevelPrefix(RoundManager __instance, int randomSeed, SelectableLevel newLevel) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown Plugin.IsNutcrackerApocalypseActive = false; if ((Object)(object)newLevel == (Object)null) { return; } string text = newLevel.sceneName ?? ""; if (!text.ToLower().Contains("antigravity") && !text.ToLower().Contains("rend")) { return; } float num = Random.Range(0f, 100f); if (Plugin.ConfigForceApocalypse.Value || num < Plugin.ConfigApocalypseChance.Value) { Plugin.IsNutcrackerApocalypseActive = true; EnemyType val = FindNutcrackerEnemyType(); if ((Object)(object)val != (Object)null) { newLevel.Enemies.Clear(); SpawnableEnemyWithRarity item = new SpawnableEnemyWithRarity(val, 100); newLevel.Enemies.Add(item); float num2 = 20f + 30f * Mathf.Pow(Random.value, 3f); int minEnemiesToSpawn = Mathf.RoundToInt(num2); __instance.minEnemiesToSpawn = minEnemiesToSpawn; __instance.currentMaxInsidePower = 9999f; __instance.cannotSpawnMoreInsideEnemies = false; } else { Plugin.IsNutcrackerApocalypseActive = false; } } } [HarmonyPatch(typeof(RoundManager), "AdvanceHourAndSpawnNewBatchOfEnemies")] [HarmonyPrefix] public static void AdvanceHourAndSpawnNewBatchOfEnemiesPrefix(RoundManager __instance) { if (Plugin.IsNutcrackerApocalypseActive) { __instance.currentMaxInsidePower = 9999f; __instance.cannotSpawnMoreInsideEnemies = false; } } [HarmonyPatch(typeof(RoundManager), "SpawnInsideEnemiesFromVentsIfReady")] [HarmonyPrefix] public static bool SpawnInsideEnemiesFromVentsIfReadyPrefix(RoundManager __instance) { if (Plugin.IsNutcrackerApocalypseActive && Plugin.ConfigInstantSpawn.Value) { if (__instance.allEnemyVents == null) { return true; } for (int i = 0; i < __instance.allEnemyVents.Length; i++) { EnemyVent val = __instance.allEnemyVents[i]; if ((Object)(object)val != (Object)null && val.occupied) { __instance.SpawnEnemyFromVent(val); } } __instance.currentEnemySpawnIndex = __instance.enemySpawnTimes.Count; return false; } return true; } }