Decompiled source of LethalLib v0.16.1
plugins/LethalLib/LethalLib.dll
Decompiled 4 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using DunGen; using DunGen.Graph; using LethalLib.Extras; using LethalLib.Modules; using LethalLib.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("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: AssemblyCompany("Evaisa")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Content-addition API for Lethal Company")] [assembly: AssemblyFileVersion("0.16.1.0")] [assembly: AssemblyInformationalVersion("0.16.1+1544246572e61ff167c447c6c4ceee7f9c8c05d5")] [assembly: AssemblyProduct("LethalLib")] [assembly: AssemblyTitle("LethalLib")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/EvaisaDev/LethalLib")] [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 LethalLib { [BepInPlugin("evaisa.lethallib", "LethalLib", "0.16.1")] public class Plugin : BaseUnityPlugin { public const string ModGUID = "evaisa.lethallib"; public const string ModName = "LethalLib"; public const string ModVersion = "0.16.1"; 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_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Expected O, but got Unknown //IL_0092: 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)"LethalLib loaded!!"); extendedLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ExtendedLogging", false, "Enable extended logging"); MainAssets = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "lethallib")); new ILHook((MethodBase)typeof(StackTrace).GetMethod("AddFrames", BindingFlags.Instance | BindingFlags.NonPublic), new Manipulator(IlHook)); Enemies.Init(); Items.Init(); Unlockables.Init(); MapObjects.Init(); Dungeon.Init(); Weathers.Init(); Player.Init(); Utilities.Init(); NetworkPrefabs.Init(); } private void IlHook(ILContext il) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown ILCursor val = new ILCursor(il); MethodInfo getFileLineNumberMethod = typeof(StackFrame).GetMethod("GetFileLineNumber", BindingFlags.Instance | BindingFlags.Public); if (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction x) => ILPatternMatchingExt.MatchCallvirt(x, (MethodBase)getFileLineNumberMethod) })) { val.RemoveRange(2); val.EmitDelegate<Func<StackFrame, string>>((Func<StackFrame, string>)GetLineOrIL); } } private static string GetLineOrIL(StackFrame instance) { int fileLineNumber = instance.GetFileLineNumber(); if (fileLineNumber == -1 || fileLineNumber == 0) { return "IL_" + instance.GetILOffset().ToString("X4"); } return fileLineNumber.ToString(); } } public static class MyPluginInfo { public const string PLUGIN_GUID = "LethalLib"; public const string PLUGIN_NAME = "LethalLib"; public const string PLUGIN_VERSION = "0.16.1"; } } namespace LethalLib.Modules { public class ContentLoader { public class CustomContent { private string id = ""; public string ID => id; public CustomContent(string id) { this.id = id; } } public class CustomItem : CustomContent { public Action<Item> registryCallback = delegate { }; public string contentPath = ""; internal Item item; public Item Item => item; public CustomItem(string id, string contentPath, Action<Item> registryCallback = null) : base(id) { this.contentPath = contentPath; if (registryCallback != null) { this.registryCallback = registryCallback; } } } public class ShopItem : CustomItem { public int initPrice; public string buyNode1Path; public string buyNode2Path; public string itemInfoPath; public void RemoveFromShop() { Items.RemoveShopItem(base.Item); } public void SetPrice(int price) { Items.UpdateShopItemPrice(base.Item, price); } public ShopItem(string id, string contentPath, int price = 0, string buyNode1Path = null, string buyNode2Path = null, string itemInfoPath = null, Action<Item> registryCallback = null) : base(id, contentPath, registryCallback) { initPrice = price; this.buyNode1Path = buyNode1Path; this.buyNode2Path = buyNode2Path; this.itemInfoPath = itemInfoPath; } } public class ScrapItem : CustomItem { public Dictionary<Levels.LevelTypes, int> levelRarities = new Dictionary<Levels.LevelTypes, int>(); public Dictionary<string, int> customLevelRarities = new Dictionary<string, int>(); public int Rarity => 0; public void RemoveFromLevels(Levels.LevelTypes levelFlags) { Items.RemoveScrapFromLevels(base.Item, levelFlags); } public ScrapItem(string id, string contentPath, int rarity, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null, Action<Item> registryCallback = null) : base(id, contentPath, registryCallback) { if (levelFlags != Levels.LevelTypes.None) { levelRarities.Add(levelFlags, rarity); } else if (levelOverrides != null) { foreach (string key in levelOverrides) { customLevelRarities.Add(key, rarity); } } } public ScrapItem(string id, string contentPath, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null, Action<Item> registryCallback = null) : base(id, contentPath, registryCallback) { if (levelRarities != null) { this.levelRarities = levelRarities; } if (customLevelRarities != null) { this.customLevelRarities = customLevelRarities; } } } public class Unlockable : CustomContent { public Action<UnlockableItem> registryCallback = delegate { }; internal UnlockableItem unlockable; public string contentPath = ""; public int initPrice; public string buyNode1Path; public string buyNode2Path; public string itemInfoPath; public StoreType storeType; public UnlockableItem UnlockableItem => unlockable; public void RemoveFromShop() { Unlockables.DisableUnlockable(UnlockableItem); } public void SetPrice(int price) { Unlockables.UpdateUnlockablePrice(UnlockableItem, price); } public Unlockable(string id, string contentPath, int price = 0, string buyNode1Path = null, string buyNode2Path = null, string itemInfoPath = null, StoreType storeType = StoreType.None, Action<UnlockableItem> registryCallback = null) : base(id) { this.contentPath = contentPath; if (registryCallback != null) { this.registryCallback = registryCallback; } initPrice = price; this.buyNode1Path = buyNode1Path; this.buyNode2Path = buyNode2Path; this.itemInfoPath = itemInfoPath; this.storeType = storeType; } } public class CustomEnemy : CustomContent { public Action<EnemyType> registryCallback = delegate { }; public string contentPath = ""; internal EnemyType enemy; public string infoNodePath; public string infoKeywordPath; public int rarity; public Levels.LevelTypes LevelTypes = Levels.LevelTypes.None; public string[] levelOverrides; public Enemies.SpawnType spawnType = (Enemies.SpawnType)(-1); public EnemyType Enemy => enemy; public void RemoveFromLevels(Levels.LevelTypes levelFlags) { Enemies.RemoveEnemyFromLevels(Enemy, levelFlags); } public CustomEnemy(string id, string contentPath, int rarity = 0, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, Enemies.SpawnType spawnType = (Enemies.SpawnType)(-1), string[] levelOverrides = null, string infoNodePath = null, string infoKeywordPath = null, Action<EnemyType> registryCallback = null) : base(id) { this.contentPath = contentPath; if (registryCallback != null) { this.registryCallback = registryCallback; } this.infoNodePath = infoNodePath; this.infoKeywordPath = infoKeywordPath; this.rarity = rarity; LevelTypes = levelFlags; this.levelOverrides = levelOverrides; this.spawnType = spawnType; } } public class MapHazard : CustomContent { public Action<SpawnableMapObjectDef> registryCallback = delegate { }; public string contentPath = ""; internal SpawnableMapObjectDef hazard; public Func<SelectableLevel, AnimationCurve> spawnRateFunction; public Levels.LevelTypes LevelTypes = Levels.LevelTypes.None; public string[] levelOverrides; public SpawnableMapObjectDef Hazard => hazard; public void RemoveFromLevels(Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null) { MapObjects.RemoveMapObject(Hazard, levelFlags, levelOverrides); } public MapHazard(string id, string contentPath, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null, Action<SpawnableMapObjectDef> registryCallback = null) : base(id) { this.contentPath = contentPath; if (registryCallback != null) { this.registryCallback = registryCallback; } LevelTypes = levelFlags; this.levelOverrides = levelOverrides; this.spawnRateFunction = spawnRateFunction; } } public class OutsideObject : CustomContent { public Action<SpawnableOutsideObjectDef> registryCallback = delegate { }; public string contentPath = ""; internal SpawnableOutsideObjectDef mapObject; public Func<SelectableLevel, AnimationCurve> spawnRateFunction; public Levels.LevelTypes LevelTypes = Levels.LevelTypes.None; public string[] levelOverrides; public SpawnableOutsideObjectDef MapObject => mapObject; public void RemoveFromLevels(Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null) { MapObjects.RemoveOutsideObject(MapObject, levelFlags, levelOverrides); } public OutsideObject(string id, string contentPath, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null, Action<SpawnableOutsideObjectDef> registryCallback = null) : base(id) { this.contentPath = contentPath; if (registryCallback != null) { this.registryCallback = registryCallback; } LevelTypes = levelFlags; this.levelOverrides = levelOverrides; this.spawnRateFunction = spawnRateFunction; } } public PluginInfo modInfo; private AssetBundle modBundle; public Action<CustomContent, GameObject> prefabCallback = delegate { }; public Dictionary<string, CustomContent> LoadedContent { get; } = new Dictionary<string, CustomContent>(); public string modName => modInfo.Metadata.Name; public string modVersion => modInfo.Metadata.Version.ToString(); public string modGUID => modInfo.Metadata.GUID; public ContentLoader(PluginInfo modInfo, AssetBundle modBundle, Action<CustomContent, GameObject> prefabCallback = null) { this.modInfo = modInfo; this.modBundle = modBundle; if (prefabCallback != null) { this.prefabCallback = prefabCallback; } } public ContentLoader Create(PluginInfo modInfo, AssetBundle modBundle, Action<CustomContent, GameObject> prefabCallback = null) { return new ContentLoader(modInfo, modBundle, prefabCallback); } public void Register(CustomContent content) { if (LoadedContent.ContainsKey(content.ID)) { Debug.LogError((object)("[LethalLib] " + modName + " tried to register content with ID " + content.ID + " but it already exists!")); return; } if (content is CustomItem customItem) { Item val = (customItem.item = modBundle.LoadAsset<Item>(customItem.contentPath)); NetworkPrefabs.RegisterNetworkPrefab(val.spawnPrefab); Utilities.FixMixerGroups(val.spawnPrefab); prefabCallback(customItem, val.spawnPrefab); customItem.registryCallback(val); if (content is ShopItem shopItem) { TerminalNode buyNode = null; TerminalNode buyNode2 = null; TerminalNode itemInfo = null; if (shopItem.buyNode1Path != null) { buyNode = modBundle.LoadAsset<TerminalNode>(shopItem.buyNode1Path); } if (shopItem.buyNode2Path != null) { buyNode2 = modBundle.LoadAsset<TerminalNode>(shopItem.buyNode2Path); } if (shopItem.itemInfoPath != null) { itemInfo = modBundle.LoadAsset<TerminalNode>(shopItem.itemInfoPath); } Items.RegisterShopItem(val, buyNode, buyNode2, itemInfo, shopItem.initPrice); } else if (content is ScrapItem scrapItem) { Items.RegisterScrap(val, scrapItem.levelRarities, scrapItem.customLevelRarities); } else { Items.RegisterItem(val); } } else if (content is Unlockable unlockable) { UnlockableItemDef unlockableItemDef = modBundle.LoadAsset<UnlockableItemDef>(unlockable.contentPath); if ((Object)(object)unlockableItemDef.unlockable.prefabObject != (Object)null) { NetworkPrefabs.RegisterNetworkPrefab(unlockableItemDef.unlockable.prefabObject); prefabCallback(content, unlockableItemDef.unlockable.prefabObject); Utilities.FixMixerGroups(unlockableItemDef.unlockable.prefabObject); } unlockable.unlockable = unlockableItemDef.unlockable; unlockable.registryCallback(unlockableItemDef.unlockable); TerminalNode buyNode3 = null; TerminalNode buyNode4 = null; TerminalNode itemInfo2 = null; if (unlockable.buyNode1Path != null) { buyNode3 = modBundle.LoadAsset<TerminalNode>(unlockable.buyNode1Path); } if (unlockable.buyNode2Path != null) { buyNode4 = modBundle.LoadAsset<TerminalNode>(unlockable.buyNode2Path); } if (unlockable.itemInfoPath != null) { itemInfo2 = modBundle.LoadAsset<TerminalNode>(unlockable.itemInfoPath); } Unlockables.RegisterUnlockable(unlockableItemDef, unlockable.storeType, buyNode3, buyNode4, itemInfo2, unlockable.initPrice); } else if (content is CustomEnemy customEnemy) { EnemyType val2 = modBundle.LoadAsset<EnemyType>(customEnemy.contentPath); NetworkPrefabs.RegisterNetworkPrefab(val2.enemyPrefab); Utilities.FixMixerGroups(val2.enemyPrefab); customEnemy.enemy = val2; prefabCallback(content, val2.enemyPrefab); customEnemy.registryCallback(val2); TerminalNode infoNode = null; TerminalKeyword infoKeyword = null; if (customEnemy.infoNodePath != null) { infoNode = modBundle.LoadAsset<TerminalNode>(customEnemy.infoNodePath); } if (customEnemy.infoKeywordPath != null) { infoKeyword = modBundle.LoadAsset<TerminalKeyword>(customEnemy.infoKeywordPath); } if (customEnemy.spawnType == (Enemies.SpawnType)(-1)) { Enemies.RegisterEnemy(val2, customEnemy.rarity, customEnemy.LevelTypes, customEnemy.levelOverrides, infoNode, infoKeyword); } else { Enemies.RegisterEnemy(val2, customEnemy.rarity, customEnemy.LevelTypes, customEnemy.spawnType, customEnemy.levelOverrides, infoNode, infoKeyword); } } else if (content is MapHazard mapHazard) { SpawnableMapObjectDef spawnableMapObjectDef = (mapHazard.hazard = modBundle.LoadAsset<SpawnableMapObjectDef>(mapHazard.contentPath)); NetworkPrefabs.RegisterNetworkPrefab(spawnableMapObjectDef.spawnableMapObject.prefabToSpawn); Utilities.FixMixerGroups(spawnableMapObjectDef.spawnableMapObject.prefabToSpawn); prefabCallback(content, spawnableMapObjectDef.spawnableMapObject.prefabToSpawn); mapHazard.registryCallback(spawnableMapObjectDef); MapObjects.RegisterMapObject(spawnableMapObjectDef, mapHazard.LevelTypes, mapHazard.levelOverrides, mapHazard.spawnRateFunction); } else if (content is OutsideObject outsideObject) { SpawnableOutsideObjectDef spawnableOutsideObjectDef = (outsideObject.mapObject = modBundle.LoadAsset<SpawnableOutsideObjectDef>(outsideObject.contentPath)); NetworkPrefabs.RegisterNetworkPrefab(spawnableOutsideObjectDef.spawnableMapObject.spawnableObject.prefabToSpawn); Utilities.FixMixerGroups(spawnableOutsideObjectDef.spawnableMapObject.spawnableObject.prefabToSpawn); prefabCallback(content, spawnableOutsideObjectDef.spawnableMapObject.spawnableObject.prefabToSpawn); outsideObject.registryCallback(spawnableOutsideObjectDef); MapObjects.RegisterOutsideObject(spawnableOutsideObjectDef, outsideObject.LevelTypes, outsideObject.levelOverrides, outsideObject.spawnRateFunction); } LoadedContent.Add(content.ID, content); } public void RegisterAll(CustomContent[] content) { Plugin.logger.LogInfo((object)$"[LethalLib] {modName} is registering {content.Length} content items!"); foreach (CustomContent content2 in content) { Register(content2); } } public void RegisterAll(List<CustomContent> content) { Plugin.logger.LogInfo((object)$"[LethalLib] {modName} is registering {content.Count} content items!"); foreach (CustomContent item in content) { Register(item); } } } public class Dungeon { public class CustomDungeonArchetype { public DungeonArchetype archeType; public Levels.LevelTypes LevelTypes; public int lineIndex = -1; } public class CustomGraphLine { public GraphLine graphLine; public Levels.LevelTypes LevelTypes; } public class CustomDungeon { public int rarity; public DungeonFlow dungeonFlow; public Levels.LevelTypes LevelTypes; public string[] levelOverrides; public int dungeonIndex = -1; public AudioClip firstTimeDungeonAudio; } [CompilerGenerated] private static class <>O { public static hook_GenerateNewFloor <0>__RoundManager_GenerateNewFloor; public static hook_Start <1>__RoundManager_Start; } public static List<CustomDungeonArchetype> customDungeonArchetypes = new List<CustomDungeonArchetype>(); public static List<CustomGraphLine> customGraphLines = new List<CustomGraphLine>(); public static Dictionary<string, TileSet> extraTileSets = new Dictionary<string, TileSet>(); public static Dictionary<string, GameObjectChance> extraRooms = new Dictionary<string, GameObjectChance>(); public static List<CustomDungeon> customDungeons = new List<CustomDungeon>(); 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>__RoundManager_GenerateNewFloor; if (obj == null) { hook_GenerateNewFloor val = RoundManager_GenerateNewFloor; <>O.<0>__RoundManager_GenerateNewFloor = val; obj = (object)val; } RoundManager.GenerateNewFloor += (hook_GenerateNewFloor)obj; object obj2 = <>O.<1>__RoundManager_Start; if (obj2 == null) { hook_Start val2 = RoundManager_Start; <>O.<1>__RoundManager_Start = val2; obj2 = (object)val2; } RoundManager.Start += (hook_Start)obj2; } private static void RoundManager_Start(orig_Start orig, RoundManager self) { orig.Invoke(self); } private static void RoundManager_GenerateNewFloor(orig_GenerateNewFloor orig, RoundManager self) { string name = ((Object)self.currentLevel).name; if (Enum.IsDefined(typeof(Levels.LevelTypes), name)) { Levels.LevelTypes levelEnum = (Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), name); int index = 0; self.dungeonGenerator.Generator.DungeonFlow.Lines.ForEach(delegate(GraphLine line) { foreach (CustomDungeonArchetype customDungeonArchetype in customDungeonArchetypes) { if (customDungeonArchetype.LevelTypes.HasFlag(levelEnum) && !line.DungeonArchetypes.Contains(customDungeonArchetype.archeType) && (customDungeonArchetype.lineIndex == -1 || customDungeonArchetype.lineIndex == index)) { line.DungeonArchetypes.Add(customDungeonArchetype.archeType); if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)("Added " + ((Object)customDungeonArchetype.archeType).name + " to " + name)); } } } foreach (DungeonArchetype dungeonArchetype in line.DungeonArchetypes) { string name2 = ((Object)dungeonArchetype).name; if (extraTileSets.ContainsKey(name2)) { TileSet val4 = extraTileSets[name2]; if (!dungeonArchetype.TileSets.Contains(val4)) { dungeonArchetype.TileSets.Add(val4); if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)("Added " + ((Object)val4).name + " to " + name)); } } } foreach (TileSet tileSet in dungeonArchetype.TileSets) { string name3 = ((Object)tileSet).name; if (extraRooms.ContainsKey(name3)) { GameObjectChance item = extraRooms[name3]; if (!tileSet.TileWeights.Weights.Contains(item)) { tileSet.TileWeights.Weights.Add(item); } } } } index++; }); foreach (CustomGraphLine customGraphLine in customGraphLines) { if (customGraphLine.LevelTypes.HasFlag(levelEnum) && !self.dungeonGenerator.Generator.DungeonFlow.Lines.Contains(customGraphLine.graphLine)) { self.dungeonGenerator.Generator.DungeonFlow.Lines.Add(customGraphLine.graphLine); } } } orig.Invoke(self); NetworkManager val = Object.FindObjectOfType<NetworkManager>(); RandomMapObject[] array = Object.FindObjectsOfType<RandomMapObject>(); foreach (RandomMapObject val2 in array) { for (int j = 0; j < val2.spawnablePrefabs.Count; j++) { string prefabName = ((Object)val2.spawnablePrefabs[j]).name; NetworkPrefab val3 = ((IEnumerable<NetworkPrefab>)val.NetworkConfig.Prefabs.m_Prefabs).FirstOrDefault((Func<NetworkPrefab, bool>)((NetworkPrefab x) => ((Object)x.Prefab).name == prefabName)); if (val3 != null && (Object)(object)val3.Prefab != (Object)(object)val2.spawnablePrefabs[j]) { val2.spawnablePrefabs[j] = val3.Prefab; } else if (val3 == null) { Plugin.logger.LogError((object)("DungeonGeneration - Could not find network prefab (" + prefabName + ")! Make sure your assigned prefab is registered with the network manager, or named identically to the vanilla prefab you are referencing.")); } } } } public static void AddArchetype(DungeonArchetype archetype, Levels.LevelTypes levelFlags, int lineIndex = -1) { CustomDungeonArchetype customDungeonArchetype = new CustomDungeonArchetype(); customDungeonArchetype.archeType = archetype; customDungeonArchetype.LevelTypes = levelFlags; customDungeonArchetype.lineIndex = lineIndex; customDungeonArchetypes.Add(customDungeonArchetype); } public static void AddLine(GraphLine line, Levels.LevelTypes levelFlags) { CustomGraphLine customGraphLine = new CustomGraphLine(); customGraphLine.graphLine = line; customGraphLine.LevelTypes = levelFlags; customGraphLines.Add(customGraphLine); } public static void AddLine(DungeonGraphLineDef line, Levels.LevelTypes levelFlags) { AddLine(line.graphLine, levelFlags); } public static void AddTileSet(TileSet set, string archetypeName) { extraTileSets.Add(archetypeName, set); } public static void AddRoom(GameObjectChance room, string tileSetName) { extraRooms.Add(tileSetName, room); } public static void AddRoom(GameObjectChanceDef room, string tileSetName) { AddRoom(room.gameObjectChance, tileSetName); } public static void AddDungeon(DungeonDef dungeon, Levels.LevelTypes levelFlags) { AddDungeon(dungeon.dungeonFlow, dungeon.rarity, levelFlags, dungeon.firstTimeDungeonAudio); } public static void AddDungeon(DungeonDef dungeon, Levels.LevelTypes levelFlags, string[] levelOverrides) { AddDungeon(dungeon.dungeonFlow, dungeon.rarity, levelFlags, levelOverrides, dungeon.firstTimeDungeonAudio); } public static void AddDungeon(DungeonFlow dungeon, int rarity, Levels.LevelTypes levelFlags, AudioClip firstTimeDungeonAudio = null) { customDungeons.Add(new CustomDungeon { dungeonFlow = dungeon, rarity = rarity, LevelTypes = levelFlags, firstTimeDungeonAudio = firstTimeDungeonAudio }); } public static void AddDungeon(DungeonFlow dungeon, int rarity, Levels.LevelTypes levelFlags, string[] levelOverrides = null, AudioClip firstTimeDungeonAudio = null) { customDungeons.Add(new CustomDungeon { dungeonFlow = dungeon, rarity = rarity, LevelTypes = levelFlags, firstTimeDungeonAudio = firstTimeDungeonAudio, levelOverrides = levelOverrides }); } } 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_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_020b: Unknown result type (might be due to invalid IL or missing references) //IL_0215: Expected O, but got Unknown SpawnableEnemy spawnableEnemy2 = spawnableEnemy; string text = ((Object)level).name; bool flag = spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.All) || spawnableEnemy2.levelRarities.ContainsKey(Levels.LevelTypes.Vanilla) || (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.levelRarities.ContainsKey(Levels.LevelTypes.Vanilla)) { num = spawnableEnemy2.levelRarities[Levels.LevelTypes.Vanilla]; } 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 Items { public struct ItemSaveOrderData { public int itemId; public string itemName; public string assetName; } public struct BuyableItemAssetInfo { public Item itemAsset; public TerminalKeyword keyword; } public class ScrapItem { public Item item; public Item origItem; public int rarity; public Levels.LevelTypes spawnLevels; public string[] spawnLevelOverrides; public string modName = "Unknown"; public Dictionary<string, int> customLevelRarities = new Dictionary<string, int>(); public Dictionary<Levels.LevelTypes, int> levelRarities = new Dictionary<Levels.LevelTypes, int>(); public ScrapItem(Item item, int rarity, Levels.LevelTypes spawnLevels = Levels.LevelTypes.None, string[] spawnLevelOverrides = null) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) origItem = item; if (!item.isScrap) { item = item.Clone<Item>(); item.isScrap = true; if (item.maxValue == 0 && item.minValue == 0) { item.minValue = 40; item.maxValue = 100; } else if (item.maxValue == 0) { item.maxValue = item.minValue * 2; } else if (item.minValue == 0) { item.minValue = item.maxValue / 2; } GameObject val = NetworkPrefabs.CloneNetworkPrefab(item.spawnPrefab); if ((Object)(object)val.GetComponent<GrabbableObject>() != (Object)null) { val.GetComponent<GrabbableObject>().itemProperties = item; } if ((Object)(object)val.GetComponentInChildren<ScanNodeProperties>() == (Object)null) { GameObject obj = Object.Instantiate<GameObject>(scanNodePrefab, val.transform); ((Object)obj).name = "ScanNode"; obj.transform.localPosition = new Vector3(0f, 0f, 0f); obj.GetComponent<ScanNodeProperties>().headerText = item.itemName; } item.spawnPrefab = val; } this.item = item; 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 ScrapItem(Item item, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null) { //IL_00fd: Unknown result type (might be due to invalid IL or missing references) origItem = item; if (!item.isScrap) { item = item.Clone<Item>(); item.isScrap = true; if (item.maxValue == 0 && item.minValue == 0) { item.minValue = 40; item.maxValue = 100; } else if (item.maxValue == 0) { item.maxValue = item.minValue * 2; } else if (item.minValue == 0) { item.minValue = item.maxValue / 2; } GameObject val = NetworkPrefabs.CloneNetworkPrefab(item.spawnPrefab); if ((Object)(object)val.GetComponent<GrabbableObject>() != (Object)null) { val.GetComponent<GrabbableObject>().itemProperties = item; } if ((Object)(object)val.GetComponentInChildren<ScanNodeProperties>() == (Object)null) { GameObject obj = Object.Instantiate<GameObject>(scanNodePrefab, val.transform); ((Object)obj).name = "ScanNode"; obj.transform.localPosition = new Vector3(0f, 0f, 0f); obj.GetComponent<ScanNodeProperties>().headerText = item.itemName; } item.spawnPrefab = val; } this.item = item; if (customLevelRarities != null) { this.customLevelRarities = Levels.Compatibility.LLLifyLevelRarityDictionary(customLevelRarities); } if (levelRarities != null) { this.levelRarities = levelRarities; } } } public class PlainItem { public Item item; public string modName; public PlainItem(Item item) { this.item = item; } } public class ShopItem { public Item item; public Item origItem; public TerminalNode buyNode1; public TerminalNode buyNode2; public TerminalNode itemInfo; public bool wasRemoved; public int price; public string modName; public ShopItem(Item item, TerminalNode buyNode1 = null, TerminalNode buyNode2 = null, TerminalNode itemInfo = null, int price = 0) { origItem = item; this.item = item; this.price = price; if ((Object)(object)buyNode1 != (Object)null) { this.buyNode1 = buyNode1; } if ((Object)(object)buyNode2 != (Object)null) { this.buyNode2 = buyNode2; } if ((Object)(object)itemInfo != (Object)null) { this.itemInfo = itemInfo; } } } [CompilerGenerated] private static class <>O { public static hook_Start <0>__StartOfRound_Start; public static hook_Awake <1>__Terminal_Awake; public static hook_TextPostProcess <2>__Terminal_TextPostProcess; public static hook_Start <3>__RegisterLevelScrapforLLL_RoundManager_Start; public static hook_Start <4>__RegisterLevelScrapforLE_Terminal_Start; } public static ConfigEntry<bool> useSavedataFix; public static GameObject scanNodePrefab; private static List<SelectableLevel> levelsAlreadyAddedTo = new List<SelectableLevel>(); public static List<Item> LethalLibItemList = new List<Item>(); public static List<BuyableItemAssetInfo> buyableItemAssetInfos = new List<BuyableItemAssetInfo>(); public static Terminal terminal; public static List<ScrapItem> scrapItems = new List<ScrapItem>(); public static List<ShopItem> shopItems = new List<ShopItem>(); public static List<PlainItem> plainItems = new List<PlainItem>(); public static void Init() { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown useSavedataFix = Plugin.config.Bind<bool>("Items", "EnableItemSaveFix", false, "Allow for LethalLib to store/reorder the item list, which should fix issues where items get reshuffled when loading an old save. This is experimental and may cause save corruptions occasionally."); scanNodePrefab = Plugin.MainAssets.LoadAsset<GameObject>("Assets/Custom/ItemScanNode.prefab"); 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>__Terminal_Awake; if (obj2 == null) { hook_Awake val2 = Terminal_Awake; <>O.<1>__Terminal_Awake = val2; obj2 = (object)val2; } Terminal.Awake += (hook_Awake)obj2; object obj3 = <>O.<2>__Terminal_TextPostProcess; if (obj3 == null) { hook_TextPostProcess val3 = Terminal_TextPostProcess; <>O.<2>__Terminal_TextPostProcess = val3; obj3 = (object)val3; } Terminal.TextPostProcess += (hook_TextPostProcess)obj3; } private static string Terminal_TextPostProcess(orig_TextPostProcess orig, Terminal self, string modifiedDisplayText, TerminalNode node) { List<Item> list = self.buyableItemsList.ToList(); List<Item> list2 = self.buyableItemsList.ToList(); list2.RemoveAll((Item x) => shopItems.FirstOrDefault((ShopItem item) => (Object)(object)item.origItem == (Object)(object)x || (Object)(object)item.item == (Object)(object)x)?.wasRemoved ?? false); self.buyableItemsList = list2.ToArray(); string result = orig.Invoke(self, modifiedDisplayText, node); self.buyableItemsList = list.ToArray(); return result; } private static void StartOfRound_Start(orig_Start orig, StartOfRound self) { if (useSavedataFix.Value && ((NetworkBehaviour)self).IsHost) { Plugin.logger.LogInfo((object)"Fixing Item savedata!!"); List<ItemSaveOrderData> itemList = new List<ItemSaveOrderData>(); StartOfRound.Instance.allItemsList.itemsList.ForEach(delegate(Item item) { itemList.Add(new ItemSaveOrderData { itemId = item.itemId, itemName = item.itemName, assetName = ((Object)item).name }); }); if (ES3.KeyExists("LethalLibAllItemsList", GameNetworkManager.Instance.currentSaveFileName)) { itemList = ES3.Load<List<ItemSaveOrderData>>("LethalLibAllItemsList", GameNetworkManager.Instance.currentSaveFileName); } List<Item> itemsList = StartOfRound.Instance.allItemsList.itemsList; List<Item> list = new List<Item>(); foreach (ItemSaveOrderData item2 in itemList) { Item val = ((IEnumerable<Item>)itemsList).FirstOrDefault((Func<Item, bool>)((Item x) => x.itemId == item2.itemId && x.itemName == item2.itemName && item2.assetName == ((Object)x).name)); if ((Object)(object)val != (Object)null) { list.Add(val); } else { list.Add(ScriptableObject.CreateInstance<Item>()); } } foreach (Item item3 in itemsList) { if (!list.Contains(item3)) { list.Add(item3); } } StartOfRound.Instance.allItemsList.itemsList = list; ES3.Save<List<ItemSaveOrderData>>("LethalLibAllItemsList", itemList, GameNetworkManager.Instance.currentSaveFileName); } orig.Invoke(self); } private static void RegisterLevelScrapforLLL_RoundManager_Start(orig_Start orig, RoundManager self) { orig.Invoke(self); RegisterLethalLibScrapItemsForAllLevels(); } private static void RegisterLevelScrapforLE_Terminal_Start(orig_Start orig, Terminal self) { orig.Invoke(self); RegisterLethalLibScrapItemsForAllLevels(); } private static void RegisterLethalLibScrapItemsForAllLevels() { SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { if (levelsAlreadyAddedTo.Contains(val)) { continue; } foreach (ScrapItem scrapItem in scrapItems) { AddScrapItemToLevel(scrapItem, val); } levelsAlreadyAddedTo.Add(val); } } private static void AddScrapItemToLevel(ScrapItem scrapItem, SelectableLevel level) { //IL_0209: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_021f: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Expected O, but got Unknown ScrapItem scrapItem2 = scrapItem; string text = ((Object)level).name; bool flag = scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.All) || scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.Vanilla) || (scrapItem2.customLevelRarities != null && scrapItem2.customLevelRarities.ContainsKey(text)); if (scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.Modded) && !Enum.IsDefined(typeof(Levels.LevelTypes), text)) { flag = true; } Levels.LevelTypes key = Levels.LevelTypes.None; bool flag2 = false; if (Enum.IsDefined(typeof(Levels.LevelTypes), text)) { key = (Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), text); flag2 = true; } else { text = Levels.Compatibility.GetLLLNameOfLevel(text); } if (!(flag2 || flag)) { return; } Levels.LevelTypes key2 = (flag ? Levels.LevelTypes.All : ((Levels.LevelTypes)Enum.Parse(typeof(Levels.LevelTypes), text))); if (!flag && !scrapItem2.levelRarities.ContainsKey(key2)) { return; } int rarity = 0; if (flag2 && scrapItem2.levelRarities.ContainsKey(key)) { rarity = scrapItem2.levelRarities[key]; } else if (flag2 && scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.Vanilla)) { rarity = scrapItem2.levelRarities[Levels.LevelTypes.Vanilla]; } else if (!flag2 && scrapItem2.customLevelRarities != null && scrapItem2.customLevelRarities.ContainsKey(text)) { rarity = scrapItem2.customLevelRarities[text]; } else if (!flag2 && scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.Modded)) { rarity = scrapItem2.levelRarities[Levels.LevelTypes.Modded]; } else if (scrapItem2.levelRarities.ContainsKey(Levels.LevelTypes.All)) { rarity = scrapItem2.levelRarities[Levels.LevelTypes.All]; } SpawnableItemWithRarity item = new SpawnableItemWithRarity { spawnableItem = scrapItem2.item, rarity = rarity }; if (!level.spawnableScrap.Any((SpawnableItemWithRarity x) => (Object)(object)x.spawnableItem == (Object)(object)scrapItem2.item)) { level.spawnableScrap.Add(item); if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)("To " + text + " added " + ((Object)scrapItem2.item).name)); } } } private static void RegisterScrapAsItem(StartOfRound startOfRound) { foreach (ScrapItem scrapItem in scrapItems) { if (startOfRound.allItemsList.itemsList.Contains(scrapItem.item)) { continue; } if (Plugin.extendedLogging.Value) { if (scrapItem.modName != "LethalLib") { Plugin.logger.LogInfo((object)(scrapItem.modName + " registered scrap item: " + scrapItem.item.itemName)); } else { Plugin.logger.LogInfo((object)("Registered scrap item: " + scrapItem.item.itemName)); } } LethalLibItemList.Add(scrapItem.item); startOfRound.allItemsList.itemsList.Add(scrapItem.item); } } private static void Terminal_Awake(orig_Awake orig, Terminal self) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_0579: Unknown result type (might be due to invalid IL or missing references) //IL_057e: Unknown result type (might be due to invalid IL or missing references) //IL_05b3: Unknown result type (might be due to invalid IL or missing references) //IL_05bc: Expected O, but got Unknown //IL_05be: Unknown result type (might be due to invalid IL or missing references) //IL_05c3: Unknown result type (might be due to invalid IL or missing references) //IL_05f8: Unknown result type (might be due to invalid IL or missing references) //IL_0600: Expected O, but got Unknown //IL_0663: Unknown result type (might be due to invalid IL or missing references) //IL_0668: Unknown result type (might be due to invalid IL or missing references) //IL_0670: Unknown result type (might be due to invalid IL or missing references) //IL_067d: Expected O, but got Unknown //IL_070a: Unknown result type (might be due to invalid IL or missing references) //IL_070f: Unknown result type (might be due to invalid IL or missing references) //IL_0717: Unknown result type (might be due to invalid IL or missing references) //IL_0724: Expected O, but got Unknown StartOfRound instance = StartOfRound.Instance; RegisterLethalLibScrapItemsForAllLevels(); if (Chainloader.PluginInfos.ContainsKey("imabatby.lethallevelloader") || Chainloader.PluginInfos.ContainsKey("iambatby.lethallevelloader")) { object obj = <>O.<3>__RegisterLevelScrapforLLL_RoundManager_Start; if (obj == null) { hook_Start val = RegisterLevelScrapforLLL_RoundManager_Start; <>O.<3>__RegisterLevelScrapforLLL_RoundManager_Start = val; obj = (object)val; } RoundManager.Start += (hook_Start)obj; } if (Chainloader.PluginInfos.ContainsKey("LethalExpansion")) { object obj2 = <>O.<4>__RegisterLevelScrapforLE_Terminal_Start; if (obj2 == null) { hook_Start val2 = RegisterLevelScrapforLE_Terminal_Start; <>O.<4>__RegisterLevelScrapforLE_Terminal_Start = val2; obj2 = (object)val2; } Terminal.Start += (hook_Start)obj2; } RegisterScrapAsItem(instance); foreach (ShopItem shopItem in shopItems) { if (instance.allItemsList.itemsList.Contains(shopItem.item)) { continue; } if (Plugin.extendedLogging.Value) { if (shopItem.modName != "LethalLib") { Plugin.logger.LogInfo((object)(shopItem.modName + " registered shop item: " + shopItem.item.itemName)); } else { Plugin.logger.LogInfo((object)("Registered shop item: " + shopItem.item.itemName)); } } LethalLibItemList.Add(shopItem.item); instance.allItemsList.itemsList.Add(shopItem.item); } foreach (PlainItem plainItem in plainItems) { if (instance.allItemsList.itemsList.Contains(plainItem.item)) { continue; } if (Plugin.extendedLogging.Value) { if (plainItem.modName != "LethalLib") { Plugin.logger.LogInfo((object)(plainItem.modName + " registered item: " + plainItem.item.itemName)); } else { Plugin.logger.LogInfo((object)("Registered item: " + plainItem.item.itemName)); } } LethalLibItemList.Add(plainItem.item); instance.allItemsList.itemsList.Add(plainItem.item); } terminal = self; List<Item> list = self.buyableItemsList.ToList(); TerminalKeyword val3 = self.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "buy"); TerminalNode result = val3.compatibleNouns[0].result.terminalOptions[1].result; TerminalKeyword val4 = self.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info"); Plugin.logger.LogInfo((object)$"Adding {shopItems.Count} items to terminal"); foreach (ShopItem item in shopItems) { if (list.Any((Item x) => x.itemName == item.item.itemName) && !item.wasRemoved) { Plugin.logger.LogInfo((object)("Item " + item.item.itemName + " already exists in terminal, skipping")); continue; } item.wasRemoved = false; if (item.price == -1) { item.price = item.item.creditsWorth; } else { item.item.creditsWorth = item.price; } int num = -1; if (!list.Any((Item x) => (Object)(object)x == (Object)(object)item.item)) { list.Add(item.item); } else { num = list.IndexOf(item.item); } int buyItemIndex = ((num == -1) ? (list.Count - 1) : num); string itemName = item.item.itemName; _ = itemName[itemName.Length - 1]; string text = itemName; TerminalNode val5 = item.buyNode2; if ((Object)(object)val5 == (Object)null) { val5 = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)val5).name = itemName.Replace(" ", "-") + "BuyNode2"; val5.displayText = "Ordered [variableAmount] " + text + ". Your new balance is [playerCredits].\n\nOur contractors enjoy fast, free shipping while on the job! Any purchased items will arrive hourly at your approximate location.\r\n\r\n"; val5.clearPreviousText = true; val5.maxCharactersToType = 15; } val5.buyItemIndex = buyItemIndex; val5.isConfirmationNode = false; val5.itemCost = item.price; val5.playSyncedClip = 0; TerminalNode val6 = item.buyNode1; if ((Object)(object)val6 == (Object)null) { val6 = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)val6).name = itemName.Replace(" ", "-") + "BuyNode1"; val6.displayText = "You have requested to order " + text + ". Amount: [variableAmount].\nTotal cost of items: [totalCost].\n\nPlease CONFIRM or DENY.\r\n\r\n"; val6.clearPreviousText = true; val6.maxCharactersToType = 35; } val6.buyItemIndex = buyItemIndex; val6.isConfirmationNode = true; val6.overrideOptions = true; val6.itemCost = item.price; val6.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { new CompatibleNoun { noun = self.terminalNodes.allKeywords.First((TerminalKeyword keyword2) => keyword2.word == "confirm"), result = val5 }, new CompatibleNoun { noun = self.terminalNodes.allKeywords.First((TerminalKeyword keyword2) => keyword2.word == "deny"), result = result } }; TerminalKeyword val7 = TerminalUtils.CreateTerminalKeyword(itemName.ToLowerInvariant().Replace(" ", "-"), isVerb: false, null, null, val3); List<TerminalKeyword> list2 = self.terminalNodes.allKeywords.ToList(); list2.Add(val7); self.terminalNodes.allKeywords = list2.ToArray(); List<CompatibleNoun> list3 = val3.compatibleNouns.ToList(); list3.Add(new CompatibleNoun { noun = val7, result = val6 }); val3.compatibleNouns = list3.ToArray(); TerminalNode val8 = item.itemInfo; if ((Object)(object)val8 == (Object)null) { val8 = ScriptableObject.CreateInstance<TerminalNode>(); ((Object)val8).name = itemName.Replace(" ", "-") + "InfoNode"; val8.displayText = "[No information about this object was found.]\n\n"; val8.clearPreviousText = true; val8.maxCharactersToType = 25; } self.terminalNodes.allKeywords = list2.ToArray(); List<CompatibleNoun> list4 = val4.compatibleNouns.ToList(); list4.Add(new CompatibleNoun { noun = val7, result = val8 }); val4.compatibleNouns = list4.ToArray(); BuyableItemAssetInfo buyableItemAssetInfo = default(BuyableItemAssetInfo); buyableItemAssetInfo.itemAsset = item.item; buyableItemAssetInfo.keyword = val7; BuyableItemAssetInfo item2 = buyableItemAssetInfo; buyableItemAssetInfos.Add(item2); if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)$"Added {itemName} to terminal (Item price: {val6.itemCost}, Item Index: {val6.buyItemIndex}, Terminal keyword: {val7.word})"); } } self.buyableItemsList = list.ToArray(); orig.Invoke(self); } public static void RegisterScrap(Item spawnableItem, int rarity, Levels.LevelTypes levelFlags) { Item spawnableItem2 = spawnableItem; ScrapItem scrapItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)spawnableItem2 || (Object)(object)x.item == (Object)(object)spawnableItem2); if (scrapItem != null) { if (levelFlags != Levels.LevelTypes.None) { scrapItem.levelRarities.Add(levelFlags, rarity); } } else { scrapItem = new ScrapItem(spawnableItem2, rarity, levelFlags); string name = Assembly.GetCallingAssembly().GetName().Name; scrapItem.modName = name; scrapItems.Add(scrapItem); } } public static void RegisterScrap(Item spawnableItem, int rarity, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null) { Item spawnableItem2 = spawnableItem; ScrapItem scrapItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)spawnableItem2 || (Object)(object)x.item == (Object)(object)spawnableItem2); if (scrapItem != null) { if (levelFlags != Levels.LevelTypes.None) { scrapItem.levelRarities.Add(levelFlags, rarity); } if (levelOverrides != null) { foreach (string levelName in levelOverrides) { scrapItem.customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(levelName), rarity); } } } else { scrapItem = new ScrapItem(spawnableItem2, rarity, levelFlags, levelOverrides); string name = Assembly.GetCallingAssembly().GetName().Name; scrapItem.modName = name; scrapItems.Add(scrapItem); } } public static void RegisterScrap(Item spawnableItem, Dictionary<Levels.LevelTypes, int>? levelRarities = null, Dictionary<string, int>? customLevelRarities = null) { Item spawnableItem2 = spawnableItem; ScrapItem scrapItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)spawnableItem2 || (Object)(object)x.item == (Object)(object)spawnableItem2); if (scrapItem != null) { if (levelRarities != null) { foreach (KeyValuePair<Levels.LevelTypes, int> levelRarity in levelRarities) { scrapItem.levelRarities.Add(levelRarity.Key, levelRarity.Value); } } if (customLevelRarities == null) { return; } { foreach (KeyValuePair<string, int> customLevelRarity in customLevelRarities) { scrapItem.customLevelRarities.Add(Levels.Compatibility.GetLLLNameOfLevel(customLevelRarity.Key), customLevelRarity.Value); } return; } } scrapItem = new ScrapItem(spawnableItem2, levelRarities, customLevelRarities); string name = Assembly.GetCallingAssembly().GetName().Name; scrapItem.modName = name; scrapItems.Add(scrapItem); } public static void RegisterShopItem(Item shopItem, TerminalNode buyNode1 = null, TerminalNode buyNode2 = null, TerminalNode itemInfo = null, int price = -1) { ShopItem shopItem2 = new ShopItem(shopItem, buyNode1, buyNode2, itemInfo, price); string name = Assembly.GetCallingAssembly().GetName().Name; shopItem2.modName = name; shopItems.Add(shopItem2); } public static void RegisterShopItem(Item shopItem, int price = -1) { ShopItem shopItem2 = new ShopItem(shopItem, null, null, null, price); string name = Assembly.GetCallingAssembly().GetName().Name; shopItem2.modName = name; shopItems.Add(shopItem2); } public static void RegisterItem(Item plainItem) { PlainItem plainItem2 = new PlainItem(plainItem); string name = Assembly.GetCallingAssembly().GetName().Name; plainItem2.modName = name; plainItems.Add(plainItem2); } public static void RemoveScrapFromLevels(Item scrapItem, Levels.LevelTypes levelFlags = Levels.LevelTypes.None, string[] levelOverrides = null) { Item scrapItem2 = scrapItem; 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)) { continue; } ScrapItem actualItem = scrapItems.FirstOrDefault((ScrapItem x) => (Object)(object)x.origItem == (Object)(object)scrapItem2 || (Object)(object)x.item == (Object)(object)scrapItem2); SpawnableItemWithRarity val2 = ((IEnumerable<SpawnableItemWithRarity>)val.spawnableScrap).FirstOrDefault((Func<SpawnableItemWithRarity, bool>)((SpawnableItemWithRarity x) => (Object)(object)x.spawnableItem == (Object)(object)actualItem.item)); if (val2 != null) { if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)("Removed Item " + ((Object)val2.spawnableItem).name + " from Level " + name)); } val.spawnableScrap.Remove(val2); } } } public static void RemoveShopItem(Item shopItem) { Item shopItem2 = shopItem; if (!((Object)(object)StartOfRound.Instance != (Object)null)) { return; } ShopItem actualItem = shopItems.FirstOrDefault((ShopItem x) => (Object)(object)x.origItem == (Object)(object)shopItem2 || (Object)(object)x.item == (Object)(object)shopItem2); actualItem.wasRemoved = true; List<TerminalKeyword> list = terminal.terminalNodes.allKeywords.ToList(); TerminalKeyword obj = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "info"); TerminalKeyword val = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "buy"); List<CompatibleNoun> list2 = val.compatibleNouns.ToList(); List<CompatibleNoun> list3 = obj.compatibleNouns.ToList(); if (buyableItemAssetInfos.Any((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)actualItem.item)) { BuyableItemAssetInfo asset = buyableItemAssetInfos.First((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)actualItem.item); list.Remove(asset.keyword); list2.RemoveAll((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword); list3.RemoveAll((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword); } terminal.terminalNodes.allKeywords = list.ToArray(); val.compatibleNouns = list2.ToArray(); obj.compatibleNouns = list3.ToArray(); } public static void UpdateShopItemPrice(Item shopItem, int price) { Item shopItem2 = shopItem; if (!((Object)(object)StartOfRound.Instance != (Object)null)) { return; } ShopItem actualItem = shopItems.FirstOrDefault((ShopItem x) => (Object)(object)x.origItem == (Object)(object)shopItem2 || (Object)(object)x.item == (Object)(object)shopItem2); actualItem.item.creditsWorth = price; TerminalKeyword obj = terminal.terminalNodes.allKeywords.First((TerminalKeyword keyword) => keyword.word == "buy"); _ = obj.compatibleNouns[0].result.terminalOptions[1].result; List<CompatibleNoun> source = obj.compatibleNouns.ToList(); if (!buyableItemAssetInfos.Any((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)actualItem.item)) { return; } BuyableItemAssetInfo asset = buyableItemAssetInfos.First((BuyableItemAssetInfo x) => (Object)(object)x.itemAsset == (Object)(object)actualItem.item); if (!source.Any((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword)) { return; } TerminalNode result = source.First((CompatibleNoun noun) => (Object)(object)noun.noun == (Object)(object)asset.keyword).result; result.itemCost = price; if (result.terminalOptions.Length == 0) { return; } CompatibleNoun[] terminalOptions = result.terminalOptions; foreach (CompatibleNoun val in terminalOptions) { if ((Object)(object)val.result != (Object)null && val.result.buyItemIndex != -1) { val.result.itemCost = price; } } } } 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, AdamanceLevel = 0x800, ArtificeLevel = 0x1000, EmbrionLevel = 0x2000, Vanilla = 0x3BFC, 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 MapObjects { public class RegisteredMapObject { public SpawnableMapObject mapObject; public SpawnableOutsideObjectWithRarity outsideObject; public Levels.LevelTypes levels; public string[] spawnLevelOverrides; public Func<SelectableLevel, AnimationCurve> spawnRateFunction; } [CompilerGenerated] private static class <>O { public static hook_Awake <0>__StartOfRound_Awake; public static hook_SpawnMapObjects <1>__RoundManager_SpawnMapObjects; } public static List<RegisteredMapObject> mapObjects = new List<RegisteredMapObject>(); 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_Awake; if (obj == null) { hook_Awake val = StartOfRound_Awake; <>O.<0>__StartOfRound_Awake = val; obj = (object)val; } StartOfRound.Awake += (hook_Awake)obj; object obj2 = <>O.<1>__RoundManager_SpawnMapObjects; if (obj2 == null) { hook_SpawnMapObjects val2 = RoundManager_SpawnMapObjects; <>O.<1>__RoundManager_SpawnMapObjects = val2; obj2 = (object)val2; } RoundManager.SpawnMapObjects += (hook_SpawnMapObjects)obj2; } private static void RoundManager_SpawnMapObjects(orig_SpawnMapObjects orig, RoundManager self) { RandomMapObject[] array = Object.FindObjectsOfType<RandomMapObject>(); foreach (RandomMapObject val in array) { foreach (RegisteredMapObject mapObject in mapObjects) { if (mapObject.mapObject != null && !val.spawnablePrefabs.Any((GameObject prefab) => (Object)(object)prefab == (Object)(object)mapObject.mapObject.prefabToSpawn)) { val.spawnablePrefabs.Add(mapObject.mapObject.prefabToSpawn); } } } orig.Invoke(self); } private static void StartOfRound_Awake(orig_Awake orig, StartOfRound self) { orig.Invoke(self); foreach (RegisteredMapObject mapObject in mapObjects) { SelectableLevel[] levels = self.levels; foreach (SelectableLevel val in levels) { string name = ((Object)val).name; bool flag = mapObject.levels.HasFlag(Levels.LevelTypes.All) || (mapObject.spawnLevelOverrides != null && mapObject.spawnLevelOverrides.Any((string item) => item.ToLowerInvariant() == name.ToLowerInvariant())); if (mapObject.levels.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 && !mapObject.levels.HasFlag(levelTypes)) { continue; } if (mapObject.mapObject != null) { if (val.spawnableMapObjects.Any((SpawnableMapObject x) => (Object)(object)x.prefabToSpawn == (Object)(object)mapObject.mapObject.prefabToSpawn)) { List<SpawnableMapObject> list = val.spawnableMapObjects.ToList(); list.RemoveAll((SpawnableMapObject x) => (Object)(object)x.prefabToSpawn == (Object)(object)mapObject.mapObject.prefabToSpawn); val.spawnableMapObjects = list.ToArray(); } SpawnableMapObject mapObject2 = mapObject.mapObject; if (mapObject.spawnRateFunction != null) { mapObject2.numberToSpawn = mapObject.spawnRateFunction(val); } List<SpawnableMapObject> list2 = val.spawnableMapObjects.ToList(); list2.Add(mapObject2); val.spawnableMapObjects = list2.ToArray(); if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)("Added " + ((Object)mapObject2.prefabToSpawn).name + " to " + name)); } } else { if (mapObject.outsideObject == null) { continue; } if (val.spawnableOutsideObjects.Any((SpawnableOutsideObjectWithRarity x) => (Object)(object)x.spawnableObject.prefabToSpawn == (Object)(object)mapObject.outsideObject.spawnableObject.prefabToSpawn)) { List<SpawnableOutsideObjectWithRarity> list3 = val.spawnableOutsideObjects.ToList(); list3.RemoveAll((SpawnableOutsideObjectWithRarity x) => (Object)(object)x.spawnableObject.prefabToSpawn == (Object)(object)mapObject.outsideObject.spawnableObject.prefabToSpawn); val.spawnableOutsideObjects = list3.ToArray(); } SpawnableOutsideObjectWithRarity outsideObject = mapObject.outsideObject; if (mapObject.spawnRateFunction != null) { outsideObject.randomAmount = mapObject.spawnRateFunction(val); } List<SpawnableOutsideObjectWithRarity> list4 = val.spawnableOutsideObjects.ToList(); list4.Add(outsideObject); val.spawnableOutsideObjects = list4.ToArray(); if (Plugin.extendedLogging.Value) { Plugin.logger.LogInfo((object)("Added " + ((Object)outsideObject.spawnableObject.prefabToSpawn).name + " to " + name)); } } } } } public static void RegisterMapObject(SpawnableMapObjectDef mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null) { RegisterMapObject(mapObject.spawnableMapObject, levels, spawnRateFunction); } public static void RegisterMapObject(SpawnableMapObjectDef mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null) { RegisterMapObject(mapObject.spawnableMapObject, levels, levelOverrides, spawnRateFunction); } public static void RegisterMapObject(SpawnableMapObject mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null) { mapObjects.Add(new RegisteredMapObject { mapObject = mapObject, levels = levels, spawnRateFunction = spawnRateFunction }); } public static void RegisterMapObject(SpawnableMapObject mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null) { mapObjects.Add(new RegisteredMapObject { mapObject = mapObject, levels = levels, spawnRateFunction = spawnRateFunction, spawnLevelOverrides = levelOverrides }); } public static void RegisterOutsideObject(SpawnableOutsideObjectDef mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null) { RegisterOutsideObject(mapObject.spawnableMapObject, levels, spawnRateFunction); } public static void RegisterOutsideObject(SpawnableOutsideObjectDef mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null) { RegisterOutsideObject(mapObject.spawnableMapObject, levels, levelOverrides, spawnRateFunction); } public static void RegisterOutsideObject(SpawnableOutsideObjectWithRarity mapObject, Levels.LevelTypes levels, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null) { mapObjects.Add(new RegisteredMapObject { outsideObject = mapObject, levels = levels, spawnRateFunction = spawnRateFunction }); } public static void RegisterOutsideObject(SpawnableOutsideObjectWithRarity mapObject, Levels.LevelTypes levels = Levels.LevelTypes.None, string[] levelOverrides = null, Func<SelectableLevel, AnimationCurve> spawnRateFunction = null) { mapObjects.Add(new RegisteredMapObject { outsideObject = mapObject, levels = levels, spawnRateFunction = spawnRateFunction, spawnLevelOverrides = levelOverrides }); } public static void RemoveMapObject(SpawnableMapObjectDef mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null) { RemoveMapObject(mapObject.spawnableMapObject, levelFlags, levelOverrides); } public static void RemoveMapObject(SpawnableMapObject mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null) { SpawnableMapObject mapObject2 = mapObject; if (!((Object)(object)StartOfRound.Instance != (Object)null)) { return; } SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { string name = ((Object)val).name; bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => 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)) { val.spawnableMapObjects = val.spawnableMapObjects.Where((SpawnableMapObject x) => (Object)(object)x.prefabToSpawn != (Object)(object)mapObject2.prefabToSpawn).ToArray(); } } } public static void RemoveOutsideObject(SpawnableOutsideObjectDef mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null) { RemoveOutsideObject(mapObject.spawnableMapObject, levelFlags, levelOverrides); } public static void RemoveOutsideObject(SpawnableOutsideObjectWithRarity mapObject, Levels.LevelTypes levelFlags, string[] levelOverrides = null) { SpawnableOutsideObjectWithRarity mapObject2 = mapObject; if (!((Object)(object)StartOfRound.Instance != (Object)null)) { return; } SelectableLevel[] levels = StartOfRound.Instance.levels; foreach (SelectableLevel val in levels) { string name = ((Object)val).name; bool flag = levelFlags.HasFlag(Levels.LevelTypes.All) || (levelOverrides?.Any((string item) => 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)) { val.spawnableOutsideObjects = val.spawnableOutsideObjects.Where((SpawnableOutsideObjectWithRarity x) => (Object)(object)x.spawnableObject.prefabToSpawn != (Object)(object)mapObject2.spawnableObject.prefabToSpawn).ToArray(); } } } } 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); } } public static GameObject CreateNetworkPrefab(string name) { GameObject obj = PrefabUtils.CreatePrefab(name); obj.AddComponent<NetworkObject>(); byte[] value = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(Assembly.GetCallingAssembly().GetName().Name + name)); obj.GetComponent<NetworkObject>().GlobalObjectIdHash = BitConverter.ToUInt32(value, 0); RegisterNetworkPrefab(obj); return obj; } public static GameObject CloneNetworkPrefab(GameObject prefabToClone, string newName = null) { GameObject val = PrefabUtils.ClonePrefab(prefabToClone, newName); byte[] value = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(Assembly.GetCallingAssembly().GetName().Name + ((Object)val).name)); val.GetComponent<NetworkObject>().GlobalObjectIdHash = BitConverter.ToUInt32(value, 0); RegisterNetworkPrefab(val); return val; } private static void GameNetworkManager_Start(orig_Start orig, GameNetworkManager self) { orig.Invoke(self); foreach (GameObject networkPrefab in _networkPrefabs) { if (!NetworkManager.Singleton.NetworkConfig.Prefabs.Contains(networkPrefab)) { NetworkManager.Singleton.AddNetworkPrefab(networkPrefab); } } } } public class Player { [CompilerGenerated] private static class <>O { public static hook_Awake <0>__StartOfRound_Awake; } public static Dictionary<string, GameObject> ragdollRefs = new Dictionary<string, GameObject>(); public static Dictionary<string, int> ragdollIndexes = new Dictionary<string, int>(); 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 object obj = <>O.<0>__StartOfRound_Awake; if (obj == null) { hook_Awake val = StartOfRound_Awake; <>O.<0>__StartOfRound_Awake = val; obj = (object)val; } StartOfRound.Awake += (hook_Awake)obj; } private static void StartOfRound_Awake(orig_Awake orig, StartOfRound self) { orig.Invoke(self); foreach (KeyValuePair<string, GameObject> ragdollRef in ragdollRefs) { if (!self.playerRagdolls.Contains(ragdollRef.Value)) { self.playerRagdolls.Add(ragdollRef.Value); int value = self.playerRagdolls.Count - 1; if (ragdollIndexes.ContainsKey(ragdollRef.Key)) { ragdollIndexes[ragdollRef.Key] = value; } else { ragdollIndexes.Add(ragdollRef.Key, value); } } } } public static int GetRagdollIndex(string id) { return ragdollIndexes[id]; } public static GameObject GetRagdoll(string id) { return ragdollRefs[id]; } public static void RegisterPlayerRagdoll(string id, GameObject ragdoll) { Plugin.logger.LogInfo((object)("Registering player ragdoll " + id)); ragdollRefs.Add(id, ragdoll); } } 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<GameObjec