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 MonsterManager v1.0.0
MonsterManager.dll
Decompiled a day agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using DunGen.Graph; using HarmonyLib; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("PowerBasedMonsters")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("PowerBasedMonsters")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("a51c141b-0511-4e04-8650-8695ac8e5c35")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace MonsterManager; [BepInPlugin("com.yourname.monstermanager", "MonsterManager", "2.4.0")] public class Plugin : BaseUnityPlugin { public static ConfigFile ConfigFile; internal static ManualLogSource mls; private readonly Harmony harmony = new Harmony("com.yourname.monstermanager"); public static ConfigEntry<bool> UseRandomization; public static ConfigEntry<int> PowerOffset; public static ConfigEntry<int> AbsoluteMaxActiveEntities; public static ConfigEntry<float> MonsterSpawnMultiplier; public static ConfigEntry<float> SpawnDistanceMultiplier; public static ConfigEntry<bool> UseExactAmountOfMonsters; public static ConfigEntry<int> ExactAmountHardMonsters; public static ConfigEntry<int> ExactAmountEasyMonsters; public static ConfigEntry<int> OffsetHardMonsters; public static ConfigEntry<int> OffsetEasyMonsters; public static ConfigEntry<float> IndoorSpawnTimeThreshold; public static ConfigEntry<float> OutdoorSpawnTimeThreshold; public static ConfigEntry<float> SpawnIntervalOffset; public static ConfigEntry<string> DefineHardMonsterPowerLevel; public static ConfigEntry<string> DefineEasyMonsterPowerLevel; public static ConfigEntry<float> DungeonSizeMultiplier; private void Awake() { mls = ((BaseUnityPlugin)this).Logger; ConfigFile = ((BaseUnityPlugin)this).Config; UseRandomization = ((BaseUnityPlugin)this).Config.Bind<bool>("1. General", "Use Randomization?", true, "If TRUE, uses the mod's custom random spawn pools and power-based equations. If FALSE and 'UseExactAmountOfMonsters' is also FALSE, the mod defaults back to vanilla game spawning."); PowerOffset = ((BaseUnityPlugin)this).Config.Bind<int>("1. General", "PowerOffset", 0, "Offset added to the moon's base power level. Can be positive or negative."); AbsoluteMaxActiveEntities = ((BaseUnityPlugin)this).Config.Bind<int>("1. General", "AbsoluteMaxActiveEntities", 40, "Hard cap on total active enemies alive on the map before the mod pauses spawning."); MonsterSpawnMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("1. General", "MonsterSpawnMultiplier", 1f, "Multiplier applied to calculated targets."); SpawnDistanceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("1. General", "SpawnDistanceMultiplier", 1f, "Controls the distance/radius from the main entrance where monsters spawn."); UseExactAmountOfMonsters = ((BaseUnityPlugin)this).Config.Bind<bool>("2. Exact Amounts", "UseExactAmountOfMonsters", false, "If TRUE, strictly uses 'ExactAmountHardMonsters' and 'ExactAmountEasyMonsters' instead of the mathematical formula."); ExactAmountHardMonsters = ((BaseUnityPlugin)this).Config.Bind<int>("2. Exact Amounts", "ExactAmountHardMonsters", 4, "Strictly sets the number of Hard monsters to spawn."); ExactAmountEasyMonsters = ((BaseUnityPlugin)this).Config.Bind<int>("2. Exact Amounts", "ExactAmountEasyMonsters", 4, "Strictly sets the number of Easy monsters to spawn."); OffsetHardMonsters = ((BaseUnityPlugin)this).Config.Bind<int>("3. Target Offsets", "OffsetHardMonsters", 0, "Adds or subtracts from the mathematically calculated Hard monster target."); OffsetEasyMonsters = ((BaseUnityPlugin)this).Config.Bind<int>("3. Target Offsets", "OffsetEasyMonsters", 0, "Adds or subtracts from the mathematically calculated Easy monster target."); IndoorSpawnTimeThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("4. Timing", "IndoorSpawnTimeThreshold", 0f, "Time of day interior monsters begin spawning (0.0 to 1.0)."); OutdoorSpawnTimeThreshold = ((BaseUnityPlugin)this).Config.Bind<float>("4. Timing", "OutdoorSpawnTimeThreshold", 0.65f, "Time of day outdoor monsters begin spawning (0.0 to 1.0)."); SpawnIntervalOffset = ((BaseUnityPlugin)this).Config.Bind<float>("4. Timing", "SpawnIntervalOffset", 0f, "Offset added or subtracted from the time between monster spawns in seconds. Can intake double values like 1.5 or negative like -1.5."); DefineHardMonsterPowerLevel = ((BaseUnityPlugin)this).Config.Bind<string>("5. Power Definitions", "DefineHardMonsterPowerLevel", ">1", "Defines required base game Power Level for a 'Hard' monster."); DefineEasyMonsterPowerLevel = ((BaseUnityPlugin)this).Config.Bind<string>("5. Power Definitions", "DefineEasyMonsterPowerLevel", "<=1", "Defines required base game Power Level for an 'Easy' monster."); DungeonSizeMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("6. Dungeon Expansion", "DungeonSizeMultiplier", 1f, "The exact size multiplier used to overwrite the facility's interior layout size."); DiscoverAndBindAllInteriors(); harmony.PatchAll(); mls.LogInfo((object)"MonsterManager v2.4.0 loaded and patched successfully!"); } public static void DiscoverAndBindAllInteriors() { //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown DungeonFlow[] array = Resources.FindObjectsOfTypeAll<DungeonFlow>(); int num = 0; DungeonFlow[] array2 = array; foreach (DungeonFlow val in array2) { if (!((Object)(object)val == (Object)null) && !string.IsNullOrEmpty(((Object)val).name)) { string text = ((Object)val).name.Replace(" ", ""); string text2 = "Expand_" + text; if (!ConfigFile.ContainsKey(new ConfigDefinition("7. Target Interiors For Expansion", text2))) { ConfigFile.Bind<bool>("7. Target Interiors For Expansion", text2, true, "If TRUE, applies the DungeonSizeMultiplier to the '" + text + "' interior layout."); num++; } } } if (num > 0) { mls.LogInfo((object)$"[INTERIOR DISCOVERY] Dynamically registered {num} new interior dungeon flows into config files."); } } } [HarmonyPatch(typeof(RoundManager))] public class SpawnEnginePatch { private static List<EnemyType> InteriorEasyPool = new List<EnemyType>(); private static List<EnemyType> InteriorHardPool = new List<EnemyType>(); private static List<EnemyType> ExteriorEasyPool = new List<EnemyType>(); private static List<EnemyType> ExteriorHardPool = new List<EnemyType>(); private static Dictionary<EnemyType, int> SpawnedCounts = new Dictionary<EnemyType, int>(); private static readonly HashSet<string> VanillaEnemyNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Flowerman", "Crawler", "Bunker Spider", "Hoarding bug", "Blob", "Centipede", "Puffer", "Jester", "Nutcracker", "Masked", "Butler", "Clay Surgeon", "Maneater", "Docile Locust Bees", "Red Locust Bees", "Baboon hawk", "MouthDog", "Forest Giant", "Earth Leviathan", "Radmech", "Tulip Snake", "Butler Bees", "Kidnapper Fox" }; private static bool EvaluatePowerLogic(float powerLevel, string logic) { logic = logic.Trim(); if (logic.StartsWith(">=") && float.TryParse(logic.Substring(2), out var result)) { return powerLevel >= result; } if (logic.StartsWith("<=") && float.TryParse(logic.Substring(2), out var result2)) { return powerLevel <= result2; } if (logic.StartsWith("==") && float.TryParse(logic.Substring(2), out var result3)) { return powerLevel == result3; } if (logic.StartsWith(">") && float.TryParse(logic.Substring(1), out var result4)) { return powerLevel > result4; } if (logic.StartsWith("<") && float.TryParse(logic.Substring(1), out var result5)) { return powerLevel < result5; } if (logic.StartsWith("=") && float.TryParse(logic.Substring(1), out var result6)) { return powerLevel == result6; } if (float.TryParse(logic, out var result7)) { return powerLevel == result7; } return false; } [HarmonyPatch("GenerateNewFloor")] [HarmonyPrefix] public static void PrefixGenerateNewFloor(RoundManager __instance) { Plugin.DiscoverAndBindAllInteriors(); Plugin.mls.LogInfo((object)"=== MOON LANDING CONFIG & COMPATIBILITY SUMMARY ==="); Plugin.mls.LogInfo((object)$"[CONFIG] Use Randomization: {Plugin.UseRandomization.Value} | Exact Amounts Enabled: {Plugin.UseExactAmountOfMonsters.Value}"); Plugin.mls.LogInfo((object)$"[CONFIG] Dungeon Multiplier: {Plugin.DungeonSizeMultiplier.Value}x | Spawn Distance: {Plugin.SpawnDistanceMultiplier.Value} | Max Active Entities: {Plugin.AbsoluteMaxActiveEntities.Value}"); Plugin.mls.LogInfo((object)$"[CONFIG] Power Offset: {Plugin.PowerOffset.Value} | Spawn Multiplier: {Plugin.MonsterSpawnMultiplier.Value}x | Interval Offset: {Plugin.SpawnIntervalOffset.Value}s"); if (!Plugin.UseRandomization.Value && !Plugin.UseExactAmountOfMonsters.Value) { Plugin.mls.LogWarning((object)"[COMPATIBILITY NOTICE] Both 'Use Randomization?' and 'UseExactAmountOfMonsters' are FALSE. DEFAULTING: Mod will step aside and use vanilla game spawning logic."); } if (!((Object)(object)__instance.currentLevel != (Object)null)) { return; } string text = "UnknownInterior"; if (__instance.currentLevel.dungeonFlowTypes != null && __instance.currentLevel.dungeonFlowTypes.Length != 0) { IntWithRarity val = __instance.currentLevel.dungeonFlowTypes.OrderByDescending((IntWithRarity f) => f.rarity).First(); if (RoundManager.Instance.dungeonFlowTypes != null && val.id >= 0 && val.id < RoundManager.Instance.dungeonFlowTypes.Length) { IndoorMapType val2 = RoundManager.Instance.dungeonFlowTypes[val.id]; if (val2 != null && (Object)(object)val2.dungeonFlow != (Object)null) { text = ((Object)val2.dungeonFlow).name.Replace(" ", ""); } } } ConfigEntry<bool> val3 = Plugin.ConfigFile.Bind<bool>("7. Target Interiors For Expansion", "Expand_" + text, true, "If TRUE, applies the DungeonSizeMultiplier to the '" + text + "' interior layout."); if (val3.Value) { __instance.currentLevel.factorySizeMultiplier = Plugin.DungeonSizeMultiplier.Value; Plugin.mls.LogInfo((object)$"[DUNGEON EXPANSION] Applied size multiplier ({Plugin.DungeonSizeMultiplier.Value}x) to active interior '{text}'."); } else { Plugin.mls.LogInfo((object)("[DUNGEON EXPANSION] Skipped expanding '" + text + "' due to configuration setting.")); } } [HarmonyPatch("BeginEnemySpawning")] [HarmonyPrefix] public static bool PrefixBeginEnemySpawning(RoundManager __instance) { if (!((NetworkBehaviour)__instance).IsServer) { return false; } if (!Plugin.UseRandomization.Value && !Plugin.UseExactAmountOfMonsters.Value) { Plugin.mls.LogInfo((object)"[SPAWN ENGINE] Bypassing custom spawner due to vanilla fallback rules."); return true; } Plugin.mls.LogInfo((object)"=== INITIALIZING MONSTER MANAGER SPAWN ENGINE ==="); InitializeGlobalMonsterPools(); SpawnedCounts.Clear(); int maxEnemyPowerCount = __instance.currentLevel.maxEnemyPowerCount; int num = ((maxEnemyPowerCount + Plugin.PowerOffset.Value <= 1) ? 1 : (maxEnemyPowerCount + Plugin.PowerOffset.Value)); CalculateTargets(num, out var hardTarget, out var easyTarget); Plugin.mls.LogInfo((object)$"[INTERIOR MATH] Effective Power: {num} | Target -> {hardTarget} Hard monsters, {easyTarget} Easy monsters"); int maxOutsideEnemyPowerCount = __instance.currentLevel.maxOutsideEnemyPowerCount; int num2 = ((maxOutsideEnemyPowerCount + Plugin.PowerOffset.Value <= 1) ? 1 : (maxOutsideEnemyPowerCount + Plugin.PowerOffset.Value)); CalculateTargets(num2, out var hardTarget2, out var easyTarget2); Plugin.mls.LogInfo((object)$"[EXTERIOR MATH] Effective Power: {num2} | Target -> {hardTarget2} Hard monsters, {easyTarget2} Easy monsters"); ((MonoBehaviour)__instance).StartCoroutine(CustomInteriorSpawnLoop(__instance)); ((MonoBehaviour)__instance).StartCoroutine(CustomExteriorSpawnLoop(__instance)); return false; } private static void InitializeGlobalMonsterPools() { InteriorEasyPool.Clear(); InteriorHardPool.Clear(); ExteriorEasyPool.Clear(); ExteriorHardPool.Clear(); EnemyType[] array = Resources.FindObjectsOfTypeAll<EnemyType>(); List<string> list = new List<string>(); EnemyType[] array2 = array; foreach (EnemyType val in array2) { if (val.isDaytimeEnemy || val.MaxCount <= 0 || (Object)(object)val.enemyPrefab == (Object)null) { continue; } string text = val.enemyName.Replace(" ", ""); ConfigEntry<bool> val2 = Plugin.ConfigFile.Bind<bool>("8. Include Monster In Random Pool", "Include_" + text, true, "If TRUE, " + val.enemyName + " is allowed into the mod's randomized spawn pools."); if (!val2.Value) { list.Add(val.enemyName); continue; } bool flag = EvaluatePowerLogic(val.PowerLevel, Plugin.DefineHardMonsterPowerLevel.Value); bool flag2 = EvaluatePowerLogic(val.PowerLevel, Plugin.DefineEasyMonsterPowerLevel.Value); if (val.isOutsideEnemy) { if (flag) { ExteriorHardPool.Add(val); } if (flag2) { ExteriorEasyPool.Add(val); } } else { if (flag) { InteriorHardPool.Add(val); } if (flag2) { InteriorEasyPool.Add(val); } } } if (list.Count > 0) { Plugin.mls.LogInfo((object)("[POOL SETUP] Excluded monsters from randomization pool: " + string.Join(", ", list))); } InteriorEasyPool = InteriorEasyPool.Distinct().ToList(); InteriorHardPool = InteriorHardPool.Distinct().ToList(); ExteriorEasyPool = ExteriorEasyPool.Distinct().ToList(); ExteriorHardPool = ExteriorHardPool.Distinct().ToList(); Plugin.mls.LogInfo((object)$"[SETUP] Interior Pools: {InteriorEasyPool.Count} Easy, {InteriorHardPool.Count} Hard."); Plugin.mls.LogInfo((object)$"[SETUP] Exterior Pools: {ExteriorEasyPool.Count} Easy, {ExteriorHardPool.Count} Hard."); } private static bool IsVanillaEnemy(EnemyType enemy) { return VanillaEnemyNames.Contains(enemy.enemyName) || VanillaEnemyNames.Contains(((Object)enemy).name); } private static void CalculateTargets(int effectivePower, out int hardTarget, out int easyTarget) { if (Plugin.UseExactAmountOfMonsters.Value) { hardTarget = Plugin.ExactAmountHardMonsters.Value; easyTarget = Plugin.ExactAmountEasyMonsters.Value; return; } double num = effectivePower; double num2 = (num - 8.0) / 14.0; if (num2 < 0.0) { num2 = 0.0; } if (num2 > 1.0) { num2 = 1.0; } double num3 = 2.0 + 4.0 * num2; double num4 = Math.Sin(num2 * Math.PI); double num5 = 3.0 + 2.0 * num4; double num6 = Plugin.MonsterSpawnMultiplier.Value; int num7 = (int)(num3 * num6 + 0.5); int num8 = (int)(num5 * num6 + 0.5); int num9 = num7 + Plugin.OffsetHardMonsters.Value; int num10 = num8 + Plugin.OffsetEasyMonsters.Value; hardTarget = ((num9 > 0) ? num9 : 0); easyTarget = ((num10 > 0) ? num10 : 0); } private static float CalculateSpawnInterval(int effectivePower) { double num = 25.0 - 10.0 * (((double)effectivePower - 8.0) / 14.0); float num2 = (float)((num > 15.0) ? num : 15.0); float num3 = num2 + Plugin.SpawnIntervalOffset.Value; if (num3 < 1f) { Plugin.mls.LogWarning((object)$"[COMPATIBILITY DEFAULT] SpawnIntervalOffset ({Plugin.SpawnIntervalOffset.Value}) pushed interval to {num3}s. DEFAULTING: Clamped to minimum safe interval of 1.0s to prevent game freezing/locking."); return 1f; } return num3; } private static IEnumerator CustomInteriorSpawnLoop(RoundManager rm) { yield return (object)new WaitUntil((Func<bool>)(() => rm.dungeonCompletedGenerating)); if (Plugin.IndoorSpawnTimeThreshold.Value > 0f) { Plugin.mls.LogInfo((object)$"[INTERIOR] Waiting for time of day to reach threshold: {Plugin.IndoorSpawnTimeThreshold.Value}"); yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)TimeOfDay.Instance != (Object)null && TimeOfDay.Instance.normalizedTimeOfDay >= Plugin.IndoorSpawnTimeThreshold.Value)); } int basePower = rm.currentLevel.maxEnemyPowerCount; int effectivePower = ((basePower + Plugin.PowerOffset.Value <= 1) ? 1 : (basePower + Plugin.PowerOffset.Value)); CalculateTargets(effectivePower, out var hardTarget, out var easyTarget); int totalMonsters = hardTarget + easyTarget; if (InteriorEasyPool.Count == 0) { hardTarget = totalMonsters; easyTarget = 0; } if (InteriorHardPool.Count == 0) { easyTarget = totalMonsters; hardTarget = 0; } float spawnInterval = CalculateSpawnInterval(effectivePower); Plugin.mls.LogInfo((object)$"[INTERIOR] Starting loop. Target: {totalMonsters} Total ({hardTarget} Hard, {easyTarget} Easy). Interval: {spawnInterval:F1}s"); int spawnedHard = 0; int spawnedEasy = 0; while (spawnedHard + spawnedEasy < totalMonsters) { yield return (object)new WaitForSeconds(spawnInterval); try { int activeEnemies = rm.SpawnedEnemies.Count((EnemyAI x) => (Object)(object)x != (Object)null && !x.isEnemyDead); if (activeEnemies < Plugin.AbsoluteMaxActiveEntities.Value) { int remainingHard = hardTarget - spawnedHard; int remainingEasy = easyTarget - spawnedEasy; bool requiresHard = false; if (remainingHard > 0 && remainingEasy > 0) { float hardProgress = ((hardTarget > 0) ? ((float)spawnedHard / (float)hardTarget) : 1f); float easyProgress = ((easyTarget > 0) ? ((float)spawnedEasy / (float)easyTarget) : 1f); requiresHard = hardProgress <= easyProgress; } else if (remainingHard > 0) { requiresHard = true; } TrySpawnMonster(rm, requiresHard, isOutside: false, ref spawnedHard, ref spawnedEasy, hardTarget, easyTarget); } } catch (Exception ex) { Plugin.mls.LogError((object)("[INTERIOR ERROR]: " + ex.Message)); } } Plugin.mls.LogInfo((object)$"[INTERIOR COMPLETE] Finished spawning all interior monsters. Final Count -> ({spawnedHard}/{hardTarget}) Hard, ({spawnedEasy}/{easyTarget}) Easy."); } private static IEnumerator CustomExteriorSpawnLoop(RoundManager rm) { Plugin.mls.LogInfo((object)$"[EXTERIOR] Waiting for time of day to reach threshold: {Plugin.OutdoorSpawnTimeThreshold.Value}"); yield return (object)new WaitUntil((Func<bool>)(() => (Object)(object)TimeOfDay.Instance != (Object)null && TimeOfDay.Instance.normalizedTimeOfDay >= Plugin.OutdoorSpawnTimeThreshold.Value)); int basePower = rm.currentLevel.maxOutsideEnemyPowerCount; int effectivePower = ((basePower + Plugin.PowerOffset.Value <= 1) ? 1 : (basePower + Plugin.PowerOffset.Value)); CalculateTargets(effectivePower, out var hardTarget, out var easyTarget); int totalMonsters = hardTarget + easyTarget; if (ExteriorEasyPool.Count == 0) { hardTarget = totalMonsters; easyTarget = 0; } if (ExteriorHardPool.Count == 0) { easyTarget = totalMonsters; hardTarget = 0; } float spawnInterval = CalculateSpawnInterval(effectivePower); Plugin.mls.LogInfo((object)$"[EXTERIOR] Starting loop. Target: {totalMonsters} Total ({hardTarget} Hard, {easyTarget} Easy). Interval: {spawnInterval:F1}s"); int spawnedHard = 0; int spawnedEasy = 0; while (spawnedHard + spawnedEasy < totalMonsters) { yield return (object)new WaitForSeconds(spawnInterval); try { int activeEnemies = rm.SpawnedEnemies.Count((EnemyAI x) => (Object)(object)x != (Object)null && !x.isEnemyDead); if (activeEnemies < Plugin.AbsoluteMaxActiveEntities.Value) { int remainingHard = hardTarget - spawnedHard; int remainingEasy = easyTarget - spawnedEasy; bool requiresHard = false; if (remainingHard > 0 && remainingEasy > 0) { float hardProgress = ((hardTarget > 0) ? ((float)spawnedHard / (float)hardTarget) : 1f); float easyProgress = ((easyTarget > 0) ? ((float)spawnedEasy / (float)easyTarget) : 1f); requiresHard = hardProgress <= easyProgress; } else if (remainingHard > 0) { requiresHard = true; } TrySpawnMonster(rm, requiresHard, isOutside: true, ref spawnedHard, ref spawnedEasy, hardTarget, easyTarget); } } catch (Exception ex) { Plugin.mls.LogError((object)("[EXTERIOR ERROR]: " + ex.Message)); } } Plugin.mls.LogInfo((object)$"[EXTERIOR COMPLETE] Finished spawning all exterior monsters. Final Count -> ({spawnedHard}/{hardTarget}) Hard, ({spawnedEasy}/{easyTarget}) Easy."); } private static bool TrySpawnMonster(RoundManager rm, bool requiresHard, bool isOutside, ref int spawnedHard, ref int spawnedEasy, int hardTarget, int easyTarget) { //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0355: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_04a7: Unknown result type (might be due to invalid IL or missing references) List<EnemyType> list = ((!requiresHard) ? (isOutside ? ExteriorEasyPool : InteriorEasyPool) : (isOutside ? ExteriorHardPool : InteriorHardPool)); if (list.Count == 0) { list = ((!requiresHard) ? (isOutside ? ExteriorHardPool : InteriorHardPool) : (isOutside ? ExteriorEasyPool : InteriorEasyPool)); if (list.Count == 0) { return false; } } EnemyType val = list[Random.Range(0, list.Count)]; if (!SpawnedCounts.ContainsKey(val)) { SpawnedCounts[val] = 0; } if (SpawnedCounts[val] >= val.MaxCount) { if (!IsVanillaEnemy(val) || !(Random.value > 0.5f)) { return false; } Plugin.mls.LogInfo((object)("[CAP BYPASS] Forcing extra vanilla spawn for " + val.enemyName + ".")); } Vector3 zero = Vector3.zero; float num = 0f; Vector3 mainEntrancePos = Vector3.zero; EntranceTeleport[] array = Object.FindObjectsOfType<EntranceTeleport>(); EntranceTeleport[] array2 = array; foreach (EntranceTeleport val2 in array2) { if ((Object)(object)val2 != (Object)null && val2.entranceId == 0) { mainEntrancePos = ((Component)val2).transform.position; break; } } if (mainEntrancePos == Vector3.zero && array.Length != 0) { mainEntrancePos = ((Component)array[0]).transform.position; } float num2 = Mathf.Clamp01(Plugin.SpawnDistanceMultiplier.Value / 2f); if (isOutside) { if (rm.outsideAINodes == null || rm.outsideAINodes.Length == 0) { return false; } List<GameObject> list2 = (from n in rm.outsideAINodes where (Object)(object)n != (Object)null orderby Vector3.Distance(n.transform.position, mainEntrancePos) select n).ToList(); if (list2.Count == 0) { return false; } int index = Mathf.Clamp(Mathf.RoundToInt((float)(list2.Count - 1) * num2), 0, list2.Count - 1); zero = list2[index].transform.position; } else { if (rm.allEnemyVents == null || rm.allEnemyVents.Length == 0) { return false; } List<EnemyVent> list3 = (from v in rm.allEnemyVents where (Object)(object)v != (Object)null && (Object)(object)v.floorNode != (Object)null orderby Vector3.Distance(v.floorNode.position, mainEntrancePos) select v).ToList(); if (list3.Count == 0) { return false; } int index2 = Mathf.Clamp(Mathf.RoundToInt((float)(list3.Count - 1) * num2), 0, list3.Count - 1); EnemyVent val3 = list3[index2]; zero = val3.floorNode.position; num = val3.floorNode.eulerAngles.y; if ((Object)(object)val3.ventAudio != (Object)null) { val3.ventAudio.Play(); } if ((Object)(object)val3.ventAnimator != (Object)null) { val3.ventAnimator.SetTrigger("open"); } } GameObject val4 = Object.Instantiate<GameObject>(val.enemyPrefab, zero, Quaternion.Euler(0f, num, 0f)); NetworkObject componentInChildren = val4.GetComponentInChildren<NetworkObject>(); if ((Object)(object)componentInChildren == (Object)null) { Object.Destroy((Object)(object)val4); return false; } componentInChildren.Spawn(true); EnemyAI component = val4.GetComponent<EnemyAI>(); if ((Object)(object)component != (Object)null) { rm.SpawnedEnemies.Add(component); } SpawnedCounts[val]++; if (requiresHard) { spawnedHard++; } else { spawnedEasy++; } Plugin.mls.LogInfo((object)string.Format("[SPAWN SUCCESS] ({0}/{1}) Hard Monsters | ({2}/{3}) Easy Monsters — Spawned {4} '{5}' at position {6}", spawnedHard, hardTarget, spawnedEasy, easyTarget, isOutside ? "Outdoor" : "Indoor", val.enemyName, zero)); return true; } }