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 LethalBestiary v1.2.1
plugins/LethalBestiary/LethalBestiary.dll
Decompiled 2 years agousing 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.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using DunGen; using DunGen.Graph; using GameNetcodeStuff; using LethalBestiary.Modules; using LethalBestiary.NetcodePatcher; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using On; using Unity.Netcode; using UnityEngine; using UnityEngine.Audio; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("Xilef992")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Lightweight version for Lethal Lib for registering new enemies!")] [assembly: AssemblyFileVersion("0.0.0.0")] [assembly: AssemblyInformationalVersion("0.0.0-dev.5+1066fcad873f53ff493f6e79e46189f3bc6bf919")] [assembly: AssemblyProduct("LethalBestiary")] [assembly: AssemblyTitle("LethalBestiary")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/FelixAllard/Xilef-LethalBestiary-LC")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] internal class <Module> { static <Module>() { } } 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 LethalBestiary { public static class MyPluginInfo { public const string PLUGIN_GUID = "LethalBestiary"; public const string PLUGIN_NAME = "LethalBestiary"; public const string PLUGIN_VERSION = "1.0.0"; } [BepInPlugin("Xilef.LethalBestiary", "LethalBestiary", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string ModGUID = "Xilef.LethalBestiary"; public const string ModName = "LethalBestiary"; public const string ModVersion = "1.0.0"; public static AssetBundle MainAssets; public static ManualLogSource logger; public static ConfigFile config; public static Plugin Instance; public static ConfigEntry<bool> extendedLogging; private void Awake() { //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) Instance = this; config = ((BaseUnityPlugin)this).Config; logger = ((BaseUnityPlugin)this).Logger; ((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalBestiary Is loading ..."); extendedLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ExtendedLogging", false, "Enable extended logging"); new ILHook((MethodBase)typeof(StackTrace).GetMethod("AddFrames", BindingFlags.Instance | BindingFlags.NonPublic), new Manipulator(IlHook)); Enemies.Init(); Utilities.Init(); NetworkPrefabs.Init(); Utilities.Init(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"LethalBestiary Is Loaded"); } private void IlHook(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown try { ILCursor val = new ILCursor(il); val.GotoNext(new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, (MethodBase)typeof(StackFrame).GetMethod("GetFileLineNumber", BindingFlags.Instance | BindingFlags.Public)) }); val.RemoveRange(2); val.EmitDelegate<Func<StackFrame, string>>((Func<StackFrame, string>)GetLineOrIL); } catch (Exception) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"ILHook already applied! LethalBestiary is skipping Method Patching!"); } } private static string GetLineOrIL(StackFrame instance) { int fileLineNumber = instance.GetFileLineNumber(); if (fileLineNumber == -1 || fileLineNumber == 0) { return "IL_" + instance.GetILOffset().ToString("X4"); } return fileLineNumber.ToString(); } } } namespace LethalBestiary.Modules { public class Enemies { public struct EnemyAssetInfo { public EnemyType EnemyAsset; public TerminalKeyword keyword; } public enum SpawnType { Default, Daytime, Outside } public class SpawnableEnemy { public EnemyType enemy; public SpawnType spawnType; public TerminalNode terminalNode; public TerminalKeyword infoKeyword; public string modName; public int rarity; public Levels.LevelTypes spawnLevels; public string[] spawnLevelOverrides; public Dictionary<string, int> customLevelRarities = new Dictionary<string, int>(); public Dictionary<Levels.LevelTypes, int> levelRarities = new Dictionary<Levels.LevelTypes, int>(); public SpawnableEnemy(EnemyType enemy, int rarity, Levels.LevelTypes spawnLevels, SpawnType spawnType, string[] spawnLevelOverrides = null) { this.enemy = enemy; this.spawnLevels = spawnLevels; this.spawnType = spawnType; if (spawnLevelOverrides != null) { foreach (string levelName in spawnLevelOverrides) { customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(levelName), rarity); } } if (spawnLevels == Levels.LevelTypes.None) { return; } foreach (Levels.LevelTypes value in Enum.GetValues(typeof(Levels.LevelTypes))) { if (spawnLevels.HasFlag(value)) { levelRarities.Add(value, rarity); } } } public SpawnableEnemy(EnemyType enemy, SpawnType spawnType, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null) { this.enemy = enemy; this.spawnType = spawnType; if (levelRarities != null) { this.levelRarities = levelRarities; } if (customLevelRarities != null) { this.customLevelRarities = Levels.Compatibility.LLLifyLevelRarityDictionary(customLevelRarities); } } } [CompilerGenerated] private static class <>O { public static hook_Awake <0>__RegisterLevelEnemies; public static hook_Start <1>__Terminal_Start; public static hook_Start <2>__QuickMenuManager_Start; public static hook_Start <3>__RegisterLevelEnemiesforLLL_RoundManager_Start; public static hook_Start <4>__RegisterLevelEnemiesforLE_Terminal_Start; } private static List<SelectableLevel> levelsAlreadyAddedTo = new List<SelectableLevel>(); private static bool addedToDebug = false; public static Terminal terminal; public static List<EnemyAssetInfo> enemyAssetInfos = new List<EnemyAssetInfo>(); public static List<SpawnableEnemy> spawnableEnemies = new List<SpawnableEnemy>(); public static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown object obj = <>O.<0>__RegisterLevelEnemies; if (obj == null) { hook_Awake val = RegisterLevelEnemies; <>O.<0>__RegisterLevelEnemies = val; obj = (object)val; } StartOfRound.Awake += (hook_Awake)obj; object obj2 = <>O.<1>__Terminal_Start; if (obj2 == null) { hook_Start val2 = Terminal_Start; <>O.<1>__Terminal_Start = val2; obj2 = (object)val2; } Terminal.Start += (hook_Start)obj2; object obj3 = <>O.<2>__QuickMenuManager_Start; if (obj3 == null) { hook_Start val3 = QuickMenuManager_Start; <>O.<2>__QuickMenuManager_Start = val3; obj3 = (object)val3; } QuickMenuManager.Start += (hook_Start)obj3; } private static void QuickMenuManager_Start(orig_Start orig, QuickMenuManager self) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown if (addedToDebug) { orig.Invoke(self); return; } SelectableLevel testAllEnemiesLevel = self.testAllEnemiesLevel; List<SpawnableEnemyWithRarity> enemies = testAllEnemiesLevel.Enemies; List<SpawnableEnemyWithRarity> daytimeEnemies = testAllEnemiesLevel.DaytimeEnemies; List<SpawnableEnemyWithRarity> outsideEnemies = testAllEnemiesLevel.OutsideEnemies; foreach (SpawnableEnemy spawnableEnemy in spawnableEnemies) { if (enemies.All((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy)) { continue; } SpawnableEnemyWithRarity item = new SpawnableEnemyWithRarity { enemyType = spawnableEnemy.enemy, rarity = spawnableEnemy.rarity }; switch (spawnableEnemy.spawnType) { case SpawnType.Default: if (!enemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy)) { enemies.Add(item); } break; case SpawnType.Daytime: if (!daytimeEnemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy)) { daytimeEnemies.Add(item); } break; case SpawnType.Outside: if (!outsideEnemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy.enemy)) { outsideEnemies.Add(item); } break; } if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)$"Added {spawnableEnemy.enemy.enemyName} to DebugList [{spawnableEnemy.spawnType}]"); } } addedToDebug = true; orig.Invoke(self); } private static void Terminal_Start(orig_Start orig, Terminal self) { //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Expected O, but got Unknown terminal = self; TerminalKeyword val = self.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info"); List<string> list = new List<string>(); foreach (SpawnableEnemy spawnableEnemy in spawnableEnemies) { if (list.Contains(spawnableEnemy.enemy.enemyName)) { Plugin.logger.LogInfo((object)("Skipping " + spawnableEnemy.enemy.enemyName + " because it was already added")); continue; } if ((Object)(object)spawnableEnemy.terminalNode == (Object)null) { spawnableEnemy.terminalNode = ScriptableObject.CreateInstance<TerminalNode>(); spawnableEnemy.terminalNode.displayText = spawnableEnemy.enemy.enemyName + "\n\nDanger level: Unknown\n\n[No information about this creature was found.]\n\n"; spawnableEnemy.terminalNode.clearPreviousText = true; spawnableEnemy.terminalNode.maxCharactersToType = 35; spawnableEnemy.terminalNode.creatureName = spawnableEnemy.enemy.enemyName; } if (self.enemyFiles.Any((TerminalNode x) => x.creatureName == spawnableEnemy.terminalNode.creatureName)) { Plugin.logger.LogInfo((object)("Skipping " + spawnableEnemy.enemy.enemyName + " because it was already added")); continue; } TerminalKeyword keyword2 = (((Object)(object)spawnableEnemy.infoKeyword != (Object)null) ? spawnableEnemy.infoKeyword : TerminalUtils.CreateTerminalKeyword(spawnableEnemy.terminalNode.creatureName.ToLowerInvariant().Replace(" ", "-"), isVerb: false, null, null, val)); keyword2.defaultVerb = val; List<TerminalKeyword> list2 = self.terminalNodes.allKeywords.ToList(); if (!list2.Any((TerminalKeyword x) => x.word == keyword2.word)) { list2.Add(keyword2); self.terminalNodes.allKeywords = list2.ToArray(); } List<CompatibleNoun> list3 = val.compatibleNouns.ToList(); if (!list3.Any((CompatibleNoun x) => x.noun.word == keyword2.word)) { list3.Add(new CompatibleNoun { noun = keyword2, result = spawnableEnemy.terminalNode }); } val.compatibleNouns = list3.ToArray(); spawnableEnemy.terminalNode.creatureFileID = self.enemyFiles.Count; self.enemyFiles.Add(spawnableEnemy.terminalNode); ScanNodeProperties[] componentsInChildren = spawnableEnemy.enemy.enemyPrefab.GetComponentsInChildren<ScanNodeProperties>(); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].creatureScanID = spawnableEnemy.terminalNode.creatureFileID; } EnemyAssetInfo enemyAssetInfo = default(EnemyAssetInfo); enemyAssetInfo.EnemyAsset = spawnableEnemy.enemy; enemyAssetInfo.keyword = keyword2; EnemyAssetInfo item = enemyAssetInfo; enemyAssetInfos.Add(item); } orig.Invoke(self); } private static void RegisterLevelEnemies(orig_Awake orig, StartOfRound self) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Expected O, but got Unknown orig.Invoke(self); RegisterLethalLibEnemiesForAllLevels(); if (Chainloader.PluginInfos.ContainsKey("imabatby.lethallevelloader") || Chainloader.PluginInfos.ContainsKey("iambatby.lethallevelloader")) { object obj = <>O.<3>__RegisterLevelEnemiesforLLL_RoundManager_Start; if (obj == null) { hook_Start val = RegisterLevelEnemiesforLLL_RoundManager_Start; <>O.<3>__RegisterLevelEnemiesforLLL_RoundManager_Start = val; obj = (object)val; } RoundManager.Start += (hook_Start)obj; } if (Chainloader.PluginInfos.ContainsKey("LethalExpansion")) { object obj2 = <>O.<4>__RegisterLevelEnemiesforLE_Terminal_Start; if (obj2 == null) { hook_Start val2 = RegisterLevelEnemiesforLE_Terminal_Start; <>O.<4>__RegisterLevelEnemiesforLE_Terminal_Start = val2; obj2 = (object)val2; } Terminal.Start += (hook_Start)obj2; } } private static void RegisterLevelEnemiesforLLL_RoundManager_Start(orig_Start orig, RoundManager self) { orig.Invoke(self); RegisterLethalLibEnemiesForAllLevels(); } private static void RegisterLevelEnemiesforLE_Terminal_Start(orig_Start orig, Terminal self) { orig.Invoke(self); RegisterLethalLibEnemiesForAllLevels(); } private static void RegisterLethalLibEnemiesForAllLevels() { SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { if (levelsAlreadyAddedTo.Contains(val)) { continue; } foreach (SpawnableEnemy spawnableEnemy in spawnableEnemies) { AddEnemyToLevel(spawnableEnemy, val); } levelsAlreadyAddedTo.Add(val); } } private static void AddEnemyToLevel(SpawnableEnemy spawnableEnemy, SelectableLevel level) { //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Expected O, but got Unknown SpawnableEnemy spawnableEnemy2 = spawnableEnemy; string text = ((Object)level).name; bool flag = spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.All) || (spawnableEnemy2.customLevelRarities != null && spawnableEnemy2.customLevelRarities.ContainsKey(text)); if (spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), text)) { flag = true; } Levels.LevelTypes levelTypes = Levels.LevelTypes.None; bool flag2 = false; if (Enum.IsDefined(typeof(Levels.LevelTypes), text)) { levelTypes = (Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), text); flag2 = true; } else { text = Levels.Compatibility.GetLLLNameOfLevel(text); } if (!(flag2 || flag)) { return; } Levels.LevelTypes key = (flag ? Levels.LevelTypes.All : levelTypes); if (!flag && !spawnableEnemy2.levelRarities.ContainsKey(key)) { return; } int num = 0; if (flag2 && spawnableEnemy2.levelRarities.ContainsKey(levelTypes)) { num = spawnableEnemy2.levelRarities[levelTypes]; } else if (!flag2 && spawnableEnemy2.customLevelRarities != null && spawnableEnemy2.customLevelRarities.ContainsKey(text)) { num = spawnableEnemy2.customLevelRarities[text]; } else if (!flag2 && spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.Modded)) { num = spawnableEnemy2.levelRarities[Levels.LevelTypes.Modded]; } else if (spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.All)) { num = spawnableEnemy2.levelRarities[Levels.LevelTypes.All]; } SpawnableEnemyWithRarity item = new SpawnableEnemyWithRarity { enemyType = spawnableEnemy2.enemy, rarity = num }; switch (spawnableEnemy2.spawnType) { case SpawnType.Default: if (!level.Enemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy2.enemy)) { level.Enemies.Add(item); if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)$"To {text} added {((Object)spawnableEnemy2.enemy).name} with weight {num} and SpawnType [Default]"); } } break; case SpawnType.Daytime: if (!level.DaytimeEnemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy2.enemy)) { level.DaytimeEnemies.Add(item); if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)$"To {text} added {((Object)spawnableEnemy2.enemy).name} with weight {num} andSpawnType [Daytime]"); } } break; case SpawnType.Outside: if (!level.OutsideEnemies.Any((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)spawnableEnemy2.enemy)) { level.OutsideEnemies.Add(item); if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)$"To {text} added {((Object)spawnableEnemy2.enemy).name} with weight {num} and SpawnType [Outside]"); } } break; } } public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, SpawnType spawnType, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null) { RegisterEnemy(enemy, rarity, levelFlags, spawnType, null, infoNode, infoKeyword); } public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, SpawnType spawnType, string[] spawnLevelOverrides = null, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null) { EnemyType enemy2 = enemy; EnemyNullCheck(enemy2); SpawnableEnemy spawnableEnemy = spawnableEnemies.FirstOrDefault((SpawnableEnemy x) => (Object)(object)x.enemy == (Object)(object)enemy2 && x.spawnType == spawnType); if (spawnableEnemy != null) { if (levelFlags != Levels.LevelTypes.None) { spawnableEnemy.levelRarities.Add(levelFlags, rarity); } if (spawnLevelOverrides != null) { foreach (string levelName in spawnLevelOverrides) { spawnableEnemy.customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(levelName), rarity); } } } else { spawnableEnemy = new SpawnableEnemy(enemy2, rarity, levelFlags, spawnType, spawnLevelOverrides); spawnableEnemy.terminalNode = infoNode; spawnableEnemy.infoKeyword = infoKeyword; FinalizeRegisterEnemy(spawnableEnemy); } } public static void RegisterEnemy(EnemyType enemy, SpawnType spawnType, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null) { EnemyType enemy2 = enemy; EnemyNullCheck(enemy2); SpawnableEnemy spawnableEnemy = spawnableEnemies.FirstOrDefault((SpawnableEnemy x) => (Object)(object)x.enemy == (Object)(object)enemy2 && x.spawnType == spawnType); if (spawnableEnemy != null) { if (levelRarities != null) { foreach (KeyValuePair<Levels.LevelTypes, int> levelRarity in levelRarities) { spawnableEnemy.levelRarities.Add(levelRarity.Key, levelRarity.Value); } } if (customLevelRarities == null) { return; } { foreach (KeyValuePair<string, int> customLevelRarity in customLevelRarities) { spawnableEnemy.customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(customLevelRarity.Key), customLevelRarity.Value); } return; } } spawnableEnemy = new SpawnableEnemy(enemy2, spawnType, levelRarities, customLevelRarities); spawnableEnemy.terminalNode = infoNode; spawnableEnemy.infoKeyword = infoKeyword; FinalizeRegisterEnemy(spawnableEnemy); } private static void FinalizeRegisterEnemy(SpawnableEnemy spawnableEnemy) { string name = Assembly.GetCallingAssembly().GetName().Name; spawnableEnemy.modName = name; if (spawnableEnemy.enemy.enemyPrefab == null) { throw new NullReferenceException("Cannot register enemy '" + spawnableEnemy.enemy.enemyName + "', because enemy.enemyPrefab is null!"); } EnemyAICollisionDetect[] componentsInChildren = spawnableEnemy.enemy.enemyPrefab.GetComponentsInChildren<EnemyAICollisionDetect>(); foreach (EnemyAICollisionDetect val in componentsInChildren) { if (val.mainScript == null) { Plugin.logger.LogWarning((object)("An Enemy AI Collision Detect Script on GameObject '" + ((Object)((Component)val).gameObject).name + "' of enemy '" + spawnableEnemy.enemy.enemyName + "' does not reference a 'Main Script', and could cause Null Reference Exceptions.")); } } spawnableEnemies.Add(spawnableEnemy); } private static void EnemyNullCheck(EnemyType enemy) { if (enemy == null) { throw new ArgumentNullException("enemy", "The first argument of RegisterEnemy was null!"); } } public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null) { EnemyNullCheck(enemy); SpawnType spawnType = (enemy.isDaytimeEnemy ? SpawnType.Daytime : (enemy.isOutsideEnemy ? SpawnType.Outside : SpawnType.Default)); RegisterEnemy(enemy, rarity, levelFlags, spawnType, null, infoNode, infoKeyword); } public static void RegisterEnemy(EnemyType enemy, int rarity, Levels.LevelTypes levelFlags, string[] spawnLevelOverrides = null, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null) { EnemyNullCheck(enemy); SpawnType spawnType = (enemy.isDaytimeEnemy ? SpawnType.Daytime : (enemy.isOutsideEnemy ? SpawnType.Outside : SpawnType.Default)); RegisterEnemy(enemy, rarity, levelFlags, spawnType, spawnLevelOverrides, infoNode, infoKeyword); } public static void RegisterEnemy(EnemyType enemy, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null, TerminalNode infoNode = null, TerminalKeyword infoKeyword = null) { EnemyNullCheck(enemy); SpawnType spawnType = (enemy.isDaytimeEnemy ? SpawnType.Daytime : (enemy.isOutsideEnemy ? SpawnType.Outside : SpawnType.Default)); RegisterEnemy(enemy, spawnType, levelRarities, customLevelRarities, infoNode, infoKeyword); } public static void RemoveEnemyFromLevels(EnemyType enemyType, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null) { EnemyType enemyType2 = enemyType; if (!((Object)(object)StartOfRound.Instance != (Object)null)) { return; } SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { string name = ((Object)val).name; if (!Enum.IsDefined(typeof(Levels.LevelTypes), name)) { name = Levels.Compatibility.GetLLLNameOfLevel(name); } bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => Levels.Compatibility.GetLLLNameOfLevel(item).ToLowerInvariant() == name.ToLowerInvariant()) ?? false); if (levelFlags.HasFlag(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), name)) { flag = true; } if (!(Enum.IsDefined(typeof(Levels.LevelTypes), name) || flag)) { continue; } Levels.LevelTypes levelTypes = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name))); if (flag || levelFlags.HasFlag(levelTypes)) { List<SpawnableEnemyWithRarity> enemies = val.Enemies; List<SpawnableEnemyWithRarity> daytimeEnemies = val.DaytimeEnemies; List<SpawnableEnemyWithRarity> outsideEnemies = val.OutsideEnemies; enemies.RemoveAll((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyType2); daytimeEnemies.RemoveAll((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyType2); outsideEnemies.RemoveAll((SpawnableEnemyWithRarity x) => (Object)(object)x.enemyType == (Object)(object)enemyType2); if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)("Removed Enemy " + ((Object)enemyType2).name + " from Level " + name)); } } } } } public class Levels { [Flags] public enum LevelTypes { None = 1, ExperimentationLevel = 4, AssuranceLevel = 8, VowLevel = 0x10, OffenseLevel = 0x20, MarchLevel = 0x40, RendLevel = 0x80, DineLevel = 0x100, TitanLevel = 0x200, Vanilla = 0x3FC, Modded = 0x400, All = -1 } internal static class Compatibility { private const string illegalCharacters = ".,?!@#$%^&*()_+-=';:'\""; private static string GetNumberlessPlanetName(string planetName) { if (planetName != null) { return new string(planetName.SkipWhile((char c) => !char.IsLetter(c)).ToArray()); } return string.Empty; } private static string StripSpecialCharacters(string input) { string text = string.Empty; for (int i = 0; i < input.Length; i++) { char c = input[i]; if ((!".,?!@#$%^&*()_+-=';:'\"".ToCharArray().Contains(c) && char.IsLetterOrDigit(c)) || c.ToString() == " ") { text += c; } } return text; } internal static string GetLLLNameOfLevel(string levelName) { string text = StripSpecialCharacters(GetNumberlessPlanetName(levelName)); if (!text.EndsWith("Level")) { text += "Level"; } return text; } internal static Dictionary<string, int> LLLifyLevelRarityDictionary(Dictionary<string, int> keyValuePairs) { Dictionary<string, int> dictionary = new Dictionary<string, int>(); List<string> list = keyValuePairs.Keys.ToList(); List<int> list2 = keyValuePairs.Values.ToList(); for (int i = 0; i < keyValuePairs.Count; i++) { dictionary.Add(GetLLLNameOfLevel(list[i]), list2[i]); } return dictionary; } } } public class NetworkPrefabs { [CompilerGenerated] private static class <>O { public static hook_Start <0>__GameNetworkManager_Start; } private static List<GameObject> _networkPrefabs = new List<GameObject>(); internal static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown object obj = <>O.<0>__GameNetworkManager_Start; if (obj == null) { hook_Start val = GameNetworkManager_Start; <>O.<0>__GameNetworkManager_Start = val; obj = (object)val; } GameNetworkManager.Start += (hook_Start)obj; } public static void RegisterNetworkPrefab(GameObject prefab) { if (prefab == null) { throw new ArgumentNullException("prefab", "The given argument for RegisterNetworkPrefab is null!"); } if (!_networkPrefabs.Contains(prefab)) { _networkPrefabs.Add(prefab); } } private static void GameNetworkManager_Start(orig_Start orig, GameNetworkManager self) { orig.Invoke(self); Debug.Log((object)"Registering All Prefabs!"); foreach (GameObject networkPrefab in _networkPrefabs) { if (!NetworkManager.Singleton.NetworkConfig.Prefabs.Contains(networkPrefab)) { NetworkManager.Singleton.AddNetworkPrefab(networkPrefab); } } } } public class PrefabUtils { internal static Lazy<GameObject> _prefabParent; internal static GameObject prefabParent => _prefabParent.Value; static PrefabUtils() { _prefabParent = new Lazy<GameObject>((Func<GameObject>)delegate { //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_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown GameObject val = new GameObject("LethalLibGeneratedPrefabs") { hideFlags = (HideFlags)61 }; val.SetActive(false); return val; }); } public static GameObject ClonePrefab(GameObject prefabToClone, string newName = null) { GameObject val = Object.Instantiate<GameObject>(prefabToClone, prefabParent.transform); ((Object)val).hideFlags = (HideFlags)61; if (newName != null) { ((Object)val).name = newName; } else { ((Object)val).name = ((Object)prefabToClone).name; } return val; } public static GameObject CreatePrefab(string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Expected O, but got Unknown GameObject val = new GameObject(name) { hideFlags = (HideFlags)61 }; val.transform.SetParent(prefabParent.transform); return val; } } public class TerminalUtils { public static TerminalKeyword CreateTerminalKeyword(string word, bool isVerb = false, CompatibleNoun[] compatibleNouns = null, TerminalNode specialKeywordResult = null, TerminalKeyword defaultVerb = null, bool accessTerminalObjects = false) { TerminalKeyword obj = ScriptableObject.CreateInstance<TerminalKeyword>(); ((Object)obj).name = word; obj.word = word; obj.isVerb = isVerb; obj.compatibleNouns = compatibleNouns; obj.specialKeywordResult = specialKeywordResult; obj.defaultVerb = defaultVerb; obj.accessTerminalObjects = accessTerminalObjects; return obj; } } public class Utilities { [CompilerGenerated] private static class <>O { public static hook_Start <0>__StartOfRound_Start; public static hook_Start <1>__MenuManager_Start; } public static List<GameObject> prefabsToFix = new List<GameObject>(); public static List<GameObject> fixedPrefabs = new List<GameObject>(); public static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown object obj = <>O.<0>__StartOfRound_Start; if (obj == null) { hook_Start val = StartOfRound_Start; <>O.<0>__StartOfRound_Start = val; obj = (object)val; } StartOfRound.Start += (hook_Start)obj; object obj2 = <>O.<1>__MenuManager_Start; if (obj2 == null) { hook_Start val2 = MenuManager_Start; <>O.<1>__MenuManager_Start = val2; obj2 = (object)val2; } MenuManager.Start += (hook_Start)obj2; } private static void StartOfRound_Start(orig_Start orig, StartOfRound self) { AudioMixer diageticMixer = SoundManager.Instance.diageticMixer; if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)("Diagetic mixer is " + ((Object)diageticMixer).name)); } Plugin.logger.LogInfo((object)$"Found {prefabsToFix.Count} prefabs to fix"); List<GameObject> list = new List<GameObject>(); for (int num = prefabsToFix.Count - 1; num >= 0; num--) { GameObject val = prefabsToFix[num]; AudioSource[] componentsInChildren = val.GetComponentsInChildren<AudioSource>(); foreach (AudioSource val2 in componentsInChildren) { if ((Object)(object)val2.outputAudioMixerGroup == (Object)null || !(((Object)val2.outputAudioMixerGroup.audioMixer).name == "Diagetic")) { continue; } AudioMixerGroup val3 = diageticMixer.FindMatchingGroups(((Object)val2.outputAudioMixerGroup).name)[0]; if ((Object)(object)val3 != (Object)null) { val2.outputAudioMixerGroup = val3; if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)("Set mixer group for " + ((Object)val2).name + " in " + ((Object)val).name + " to Diagetic:" + ((Object)val3).name)); } list.Add(val); } } } foreach (GameObject item in list) { prefabsToFix.Remove(item); } orig.Invoke(self); } private static void MenuManager_Start(orig_Start orig, MenuManager self) { orig.Invoke(self); if ((Object)(object)((Component)self).GetComponent<AudioSource>() == (Object)null) { return; } AudioMixer audioMixer = ((Component)self).GetComponent<AudioSource>().outputAudioMixerGroup.audioMixer; List<GameObject> list = new List<GameObject>(); for (int num = prefabsToFix.Count - 1; num >= 0; num--) { GameObject val = prefabsToFix[num]; AudioSource[] componentsInChildren = val.GetComponentsInChildren<AudioSource>(); foreach (AudioSource val2 in componentsInChildren) { if ((Object)(object)val2.outputAudioMixerGroup == (Object)null || !(((Object)val2.outputAudioMixerGroup.audioMixer).name == "NonDiagetic")) { continue; } AudioMixerGroup val3 = audioMixer.FindMatchingGroups(((Object)val2.outputAudioMixerGroup).name)[0]; if ((Object)(object)val3 != (Object)null) { val2.outputAudioMixerGroup = val3; if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)("Set mixer group for " + ((Object)val2).name + " in " + ((Object)val).name + " to NonDiagetic:" + ((Object)val3).name)); } list.Add(val); } } } foreach (GameObject item in list) { prefabsToFix.Remove(item); } } public static void FixMixerGroups(GameObject prefab) { if (!fixedPrefabs.Contains(prefab)) { fixedPrefabs.Add(prefab); prefabsToFix.Add(prefab); } } } } namespace LethalBestiary.Extras { [CreateAssetMenu(menuName = "ScriptableObjects/DungeonDef")] public class DungeonDef : ScriptableObject { public DungeonFlow dungeonFlow; [Range(0f, 300f)] public int rarity; public AudioClip firstTimeDungeonAudio; } [CreateAssetMenu(menuName = "ScriptableObjects/DungeonGraphLine")] public class DungeonGraphLineDef : ScriptableObject { public GraphLine graphLine; } public static class ScriptableObjectExtension { public static T Clone<T>(this T scriptableObject) where T : ScriptableObject { if ((Object)(object)scriptableObject == (Object)null) { Debug.LogError((object)$"ScriptableObject was null. Returning default {typeof(T)} object."); return (T)(object)ScriptableObject.CreateInstance(typeof(T)); } T val = Object.Instantiate<T>(scriptableObject); ((Object)(object)val).name = ((Object)(object)scriptableObject).name; return val; } } [CreateAssetMenu(menuName = "ScriptableObjects/GameObjectChance")] public class GameObjectChanceDef : ScriptableObject { public GameObjectChance gameObjectChance; } [CreateAssetMenu(menuName = "ScriptableObjects/SpawnableMapObject")] public class SpawnableMapObjectDef : ScriptableObject { public SpawnableMapObject spawnableMapObject; } [CreateAssetMenu(menuName = "ScriptableObjects/SpawnableOutsideObject")] public class SpawnableOutsideObjectDef : ScriptableObject { public SpawnableOutsideObjectWithRarity spawnableMapObject; } } namespace LethalLib { public static class MyPluginInfo { public const string PLUGIN_GUID = "LethalBestiary"; public const string PLUGIN_NAME = "LethalBestiary"; public const string PLUGIN_VERSION = "1.2.1"; } } namespace LethalLib.EnemyHelper { public static class FlashLightEnemyHelper { public static bool CheckIfEnemyFlashed(Vector3 EnemyPosition, float angle = 20f) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB[] allPlayerScripts = RoundManager.Instance.playersManager.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (!val.HasLineOfSightToPosition(EnemyPosition, 45f, 60, -1f)) { continue; } GrabbableObject[] itemSlots = val.ItemSlots; foreach (GrabbableObject val2 in itemSlots) { if ((Object)(object)val2 != (Object)null && (Object)(object)((Component)val2).gameObject.GetComponent<FlashlightItem>() != (Object)null && ((GrabbableObject)((Component)val2).gameObject.GetComponent<FlashlightItem>()).isBeingUsed && Vector3.Distance(((Component)val).transform.position, EnemyPosition) < 3f && val.LineOfSightToPositionAngle(EnemyPosition, 60, -1f) < 20f) { return true; } } } return false; } public static bool CheckIfEnemyFlashedByPlayer(Vector3 EnemyPosition, PlayerControllerB PlayerToCheck, float angle = 20f) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) if (PlayerToCheck.HasLineOfSightToPosition(EnemyPosition, 45f, 60, -1f)) { GrabbableObject[] itemSlots = PlayerToCheck.ItemSlots; foreach (GrabbableObject val in itemSlots) { if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject.GetComponent<FlashlightItem>() != (Object)null && ((GrabbableObject)((Component)val).gameObject.GetComponent<FlashlightItem>()).isBeingUsed && Vector3.Distance(((Component)PlayerToCheck).transform.position, EnemyPosition) < 3f && PlayerToCheck.LineOfSightToPositionAngle(EnemyPosition, 60, -1f) < angle) { return true; } } } return false; } public static bool CheckIfPlayerHasFlashlight(PlayerControllerB PlayerToCheck, bool CheckIfOpened) { GrabbableObject[] itemSlots = PlayerToCheck.ItemSlots; foreach (GrabbableObject val in itemSlots) { if ((Object)(object)val != (Object)null && (Object)(object)((Component)val).gameObject.GetComponent<FlashlightItem>() != (Object)null && CheckIfOpened && ((GrabbableObject)((Component)val).gameObject.GetComponent<FlashlightItem>()).isBeingUsed) { return true; } } return false; } } public static class TeleportEnemy { public static void FindValidTeleportPositionRadius(Vector3 position, float MinRadius, float MaxRadius, bool MustHavePath = true) { } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace LethalBestiary.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }