Decompiled source of LethalLevelLoader v1.2.4
plugins/LethalLevelLoader.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using DunGen; using DunGen.Graph; using GameNetcodeStuff; using HarmonyLib; using LethalLevelLoader; using LethalLevelLoader.NetcodePatcher; using LethalLevelLoader.Tools; using LethalLib.Modules; using LethalModDataLib.Base; using Microsoft.CodeAnalysis; using Mono.Cecil.Cil; using MonoMod.Cil; using MonoMod.RuntimeDetour; using On; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.Audio; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.Video; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("LethalLevelLoader")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("A Custom API to support the manual and dynamic integration of custom levels and dungeons in Lethal Company.")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0+56c63f23a250f07a0f6f37bbf22fd42c356669a8")] [assembly: AssemblyProduct("LethalLevelLoader")] [assembly: AssemblyTitle("LethalLevelLoader")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public enum ContentType { Vanilla, Custom, Any } internal static class HookHelper { public class DisposableHookCollection { private List<ILHook> ilHooks = new List<ILHook>(); private List<Hook> hooks = new List<Hook>(); public void Clear() { foreach (Hook hook in hooks) { hook.Dispose(); } hooks.Clear(); foreach (ILHook ilHook in ilHooks) { ilHook.Dispose(); } ilHooks.Clear(); } public void ILHook<T>(string methodName, Manipulator to, Type[] parameters = null) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown ilHooks.Add(new ILHook((MethodBase)EzGetMethod<T>(methodName, parameters), to)); } public void Hook<T>(string methodName, Delegate to, Type[] parameters = null) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown hooks.Add(new Hook((MethodBase)EzGetMethod<T>(methodName, parameters), to)); } } public static MethodInfo methodof(Delegate method) { return method.Method; } public static MethodInfo EzGetMethod(Type type, string name, Type[] parameters = null) { BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; if (parameters == null) { return type.GetMethod(name, bindingAttr); } return type.GetMethod(name, bindingAttr, null, parameters, null); } public static MethodInfo EzGetMethod<T>(string name, Type[] parameters = null) { return EzGetMethod(typeof(T), name, parameters); } } public static class NetworkScenePatcher { [CompilerGenerated] private static class <>O { public static Action<Action<NetworkSceneManager>, NetworkSceneManager> <0>__GenerateScenesInBuild_Hook; public static Func<Func<NetworkSceneManager, uint, string>, NetworkSceneManager, uint, string> <1>__SceneNameFromHash_Hook; public static Func<Func<NetworkSceneManager, int, string, LoadSceneMode, bool>, NetworkSceneManager, int, string, LoadSceneMode, bool> <2>__ValidateSceneBeforeLoading_Hook; public static Manipulator <3>__ReplaceBuildIndexByScenePath; public static Manipulator <4>__ReplaceScenePathByBuildIndex; public static Func<int, string> <5>__GetScenePathByBuildIndex; public static Func<string, int> <6>__GetBuildIndexByScenePath; } private static List<string> scenePaths = new List<string>(); private static Dictionary<string, int> scenePathToBuildIndex = new Dictionary<string, int>(); private static Dictionary<int, string> buildIndexToScenePath = new Dictionary<int, string>(); private static Dictionary<uint, string> sceneHashToScenePath = new Dictionary<uint, string>(); private static HookHelper.DisposableHookCollection hooks = new HookHelper.DisposableHookCollection(); internal static bool patched { get; private set; } public static void AddScenePath(string scenePath) { if (!scenePaths.Contains(scenePath)) { DebugHelper.Log("Adding ScenePath: " + scenePath, DebugType.User); scenePaths.Add(scenePath); } } internal static void Patch() { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Expected O, but got Unknown //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Expected O, but got Unknown //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Expected O, but got Unknown if (!patched) { patched = true; hooks.Hook<NetworkSceneManager>("GenerateScenesInBuild", new Action<Action<NetworkSceneManager>, NetworkSceneManager>(GenerateScenesInBuild_Hook)); hooks.Hook<NetworkSceneManager>("SceneNameFromHash", new Func<Func<NetworkSceneManager, uint, string>, NetworkSceneManager, uint, string>(SceneNameFromHash_Hook)); hooks.Hook<NetworkSceneManager>("ValidateSceneBeforeLoading", new Func<Func<NetworkSceneManager, int, string, LoadSceneMode, bool>, NetworkSceneManager, int, string, LoadSceneMode, bool>(ValidateSceneBeforeLoading_Hook), new Type[3] { typeof(int), typeof(string), typeof(LoadSceneMode) }); HookHelper.DisposableHookCollection disposableHookCollection = hooks; object obj = <>O.<3>__ReplaceBuildIndexByScenePath; if (obj == null) { Manipulator val = ReplaceBuildIndexByScenePath; <>O.<3>__ReplaceBuildIndexByScenePath = val; obj = (object)val; } disposableHookCollection.ILHook<NetworkSceneManager>("SceneHashFromNameOrPath", (Manipulator)obj); HookHelper.DisposableHookCollection disposableHookCollection2 = hooks; object obj2 = <>O.<3>__ReplaceBuildIndexByScenePath; if (obj2 == null) { Manipulator val2 = ReplaceBuildIndexByScenePath; <>O.<3>__ReplaceBuildIndexByScenePath = val2; obj2 = (object)val2; } disposableHookCollection2.ILHook<NetworkSceneManager>("ValidateSceneEvent", (Manipulator)obj2); HookHelper.DisposableHookCollection disposableHookCollection3 = hooks; object obj3 = <>O.<4>__ReplaceScenePathByBuildIndex; if (obj3 == null) { Manipulator val3 = ReplaceScenePathByBuildIndex; <>O.<4>__ReplaceScenePathByBuildIndex = val3; obj3 = (object)val3; } disposableHookCollection3.ILHook<NetworkSceneManager>("ScenePathFromHash", (Manipulator)obj3); } } internal static void Unpatch() { if (patched) { patched = false; hooks.Clear(); } } private static void ReplaceScenePathByBuildIndex(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); MethodInfo methodInfo = HookHelper.methodof(new Func<int, string>(GetScenePathByBuildIndex)); while (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction instr) => ILPatternMatchingExt.MatchCall(instr, typeof(SceneUtility), "GetScenePathByBuildIndex") })) { val.Remove(); val.Emit(OpCodes.Call, (MethodBase)methodInfo); } } private static void ReplaceBuildIndexByScenePath(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); MethodInfo methodInfo = HookHelper.methodof(new Func<string, int>(GetBuildIndexByScenePath)); while (val.TryGotoNext(new Func<Instruction, bool>[1] { (Instruction instr) => ILPatternMatchingExt.MatchCall(instr, typeof(SceneUtility), "GetBuildIndexByScenePath") })) { val.Remove(); val.Emit(OpCodes.Call, (MethodBase)methodInfo); } } private static string GetScenePathByBuildIndex(int buildIndex) { if (buildIndexToScenePath.ContainsKey(buildIndex)) { return buildIndexToScenePath[buildIndex]; } return SceneUtility.GetScenePathByBuildIndex(buildIndex); } private static int GetBuildIndexByScenePath(string scenePath) { int num = SceneUtility.GetBuildIndexByScenePath(scenePath); if (num == -1 && scenePathToBuildIndex.ContainsKey(scenePath)) { num = scenePathToBuildIndex[scenePath]; } return num; } private static void GenerateScenesInBuild_Hook(Action<NetworkSceneManager> orig, NetworkSceneManager self) { scenePathToBuildIndex.Clear(); buildIndexToScenePath.Clear(); sceneHashToScenePath.Clear(); orig(self); int sceneCountInBuildSettings = SceneManager.sceneCountInBuildSettings; for (int i = 0; i < scenePaths.Count; i++) { int num = sceneCountInBuildSettings + i; string text = scenePaths[i]; uint num2 = XXHash.Hash32(text); self.HashToBuildIndex.Add(num2, num); self.BuildIndexToHash.Add(num, num2); scenePathToBuildIndex.Add(text, num); buildIndexToScenePath.Add(num, text); sceneHashToScenePath.Add(num2, text); } } private static string SceneNameFromHash_Hook(Func<NetworkSceneManager, uint, string> orig, NetworkSceneManager self, uint sceneHash) { if (sceneHash == 0) { return "No Scene"; } if (sceneHashToScenePath.ContainsKey(sceneHash)) { return sceneHashToScenePath[sceneHash]; } return orig(self, sceneHash); } private static bool ValidateSceneBeforeLoading_Hook(Func<NetworkSceneManager, int, string, LoadSceneMode, bool> orig, NetworkSceneManager self, int sceneIndex, string sceneName, LoadSceneMode loadSceneMode) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) bool flag = orig(self, sceneIndex, sceneName, loadSceneMode); return true; } } namespace LethalLevelLoader { public class ExtendedContent : ScriptableObject { public ExtendedMod ExtendedMod { get; internal set; } public ContentType ContentType { get; internal set; } = ContentType.Vanilla; public List<string> ContentTagStrings { get; internal set; } = new List<string>(); [field: SerializeField] public List<ContentTag> ContentTags { get; internal set; } = new List<ContentTag>(); public string ModName => ExtendedMod.ModName; public string AuthorName => ExtendedMod.AuthorName; internal virtual void TryCreateMatchingProperties() { } public bool TryGetTag(string tag) { foreach (ContentTag contentTag in ContentTags) { if (contentTag.contentTagName == tag) { return true; } } return false; } public bool TryGetTag(string tag, out ContentTag returnTag) { returnTag = null; foreach (ContentTag contentTag in ContentTags) { if (contentTag.contentTagName == tag) { returnTag = contentTag; return true; } } return false; } public bool TryAddTag(string tag) { if (!TryGetTag(tag)) { ContentTags.Add(ContentTag.Create(tag)); return true; } return false; } } [Serializable] public class StringWithRarity { [SerializeField] private string _name; [SerializeField] [Range(0f, 300f)] private int _rarity; [HideInInspector] public string Name { get { return _name; } set { _name = value; } } [HideInInspector] public int Rarity { get { return _rarity; } set { _rarity = value; } } [HideInInspector] public StringWithRarity(string newName, int newRarity) { _name = newName; _rarity = newRarity; } } [Serializable] public class Vector2WithRarity { [SerializeField] private Vector2 _minMax; [SerializeField] private int _rarity; [HideInInspector] public float Min { get { return _minMax.x; } set { _minMax.x = value; } } [HideInInspector] public float Max { get { return _minMax.y; } set { _minMax.y = value; } } [HideInInspector] public int Rarity { get { return _rarity; } set { _rarity = value; } } public Vector2WithRarity(Vector2 vector2, int newRarity) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) _minMax.x = vector2.x; _minMax.y = vector2.y; _rarity = newRarity; } public Vector2WithRarity(float newMin, float newMax, int newRarity) { _minMax.x = newMin; _minMax.y = newMax; _rarity = newRarity; } } [CreateAssetMenu(fileName = "ExtendedDungeonFlow", menuName = "Lethal Level Loader/Extended Content/ExtendedDungeonFlow", order = 21)] public class ExtendedDungeonFlow : ExtendedContent { [Space(25f)] [Header("Obsolete (Legacy Fields, Will Be Removed In The Future)")] [Obsolete] public bool generateAutomaticConfigurationOptions = true; [Obsolete] public bool enableDynamicDungeonSizeRestriction = false; [Obsolete] public float dungeonSizeMin = 1f; [Obsolete] public float dungeonSizeMax = 1f; [Obsolete] [Range(0f, 1f)] public float dungeonSizeLerpPercentage = 1f; [Obsolete] public AudioClip dungeonFirstTimeAudio; [Obsolete] public DungeonFlow dungeonFlow; [Obsolete] public string dungeonDisplayName = string.Empty; [Obsolete] public string contentSourceName = string.Empty; [Obsolete] public List<StringWithRarity> dynamicLevelTagsList = new List<StringWithRarity>(); [Obsolete] public List<Vector2WithRarity> dynamicRoutePricesList = new List<Vector2WithRarity>(); [Obsolete] public List<StringWithRarity> dynamicCurrentWeatherList = new List<StringWithRarity>(); [Obsolete] public List<StringWithRarity> manualPlanetNameReferenceList = new List<StringWithRarity>(); [Obsolete] public List<StringWithRarity> manualContentSourceNameReferenceList = new List<StringWithRarity>(); [Obsolete] [HideInInspector] public int dungeonDefaultRarity; [field: Header("General Settings")] [field: SerializeField] public DungeonFlow DungeonFlow { get; set; } [field: SerializeField] public string DungeonName { get; set; } = string.Empty; [field: SerializeField] public float MapTileSize { get; set; } = 1f; [field: SerializeField] public AudioClip FirstTimeDungeonAudio { get; set; } [field: Space(5f)] [field: Header("Dynamic Injection Matching Settings")] [field: SerializeField] public LevelMatchingProperties LevelMatchingProperties { get; set; } [field: Space(5f)] [field: Header("Extended Feature Settings")] [field: SerializeField] public GameObject OverrideKeyPrefab { get; set; } [field: SerializeField] public List<SpawnableMapObject> SpawnableMapObjects { get; set; } = new List<SpawnableMapObject>(); [field: SerializeField] public List<GlobalPropCountOverride> GlobalPropCountOverridesList { get; set; } = new List<GlobalPropCountOverride>(); [field: Space(5f)] [field: SerializeField] public bool IsDynamicDungeonSizeRestrictionEnabled { get; set; } [field: SerializeField] public Vector2 DynamicDungeonSizeMinMax { get; set; } = new Vector2(1f, 1f); [field: SerializeField] [field: Range(0f, 1f)] public float DynamicDungeonSizeLerpRate { get; set; } = 1f; [field: Space(10f)] [field: Header("Misc. Settings")] [field: SerializeField] public bool GenerateAutomaticConfigurationOptions { get; set; } = true; public int DungeonID { get; internal set; } public bool IsCurrentDungeon => (Object)(object)DungeonManager.CurrentExtendedDungeonFlow == (Object)(object)this; [HideInInspector] public DungeonEvents DungeonEvents { get; internal set; } = new DungeonEvents(); internal static ExtendedDungeonFlow Create(DungeonFlow newDungeonFlow, AudioClip newFirstTimeDungeonAudio) { ExtendedDungeonFlow extendedDungeonFlow = ScriptableObject.CreateInstance<ExtendedDungeonFlow>(); extendedDungeonFlow.DungeonFlow = newDungeonFlow; extendedDungeonFlow.FirstTimeDungeonAudio = newFirstTimeDungeonAudio; if ((Object)(object)extendedDungeonFlow.LevelMatchingProperties == (Object)null) { extendedDungeonFlow.LevelMatchingProperties = LevelMatchingProperties.Create(extendedDungeonFlow); } return extendedDungeonFlow; } internal void Initialize() { if ((Object)(object)LevelMatchingProperties == (Object)null) { LevelMatchingProperties = LevelMatchingProperties.Create(this); } GetDungeonFlowID(); if (DungeonName == null || DungeonName == string.Empty) { DungeonName = ((Object)DungeonFlow).name; } ((Object)this).name = ((Object)DungeonFlow).name.Replace("Flow", "") + "ExtendedDungeonFlow"; if ((Object)(object)FirstTimeDungeonAudio == (Object)null) { DebugHelper.LogWarning("Custom Dungeon: " + DungeonName + " Is Missing A DungeonFirstTimeAudio Reference! Assigning Facility Audio To Prevent Errors.", DebugType.Developer); FirstTimeDungeonAudio = Patches.RoundManager.firstTimeDungeonAudios[0]; } if ((Object)(object)OverrideKeyPrefab == (Object)null) { OverrideKeyPrefab = DungeonLoader.defaultKeyPrefab; } } private void GetDungeonFlowID() { if (base.ContentType == ContentType.Custom) { DungeonID = PatchedContent.ExtendedDungeonFlows.Count; } if (base.ContentType != 0) { return; } IndoorMapType[] dungeonFlowTypes = Patches.RoundManager.dungeonFlowTypes; foreach (IndoorMapType val in dungeonFlowTypes) { if ((Object)(object)val.dungeonFlow == (Object)(object)DungeonFlow) { DungeonID = Patches.RoundManager.dungeonFlowTypes.ToList().IndexOf(val); } } } internal override void TryCreateMatchingProperties() { if ((Object)(object)LevelMatchingProperties == (Object)null) { LevelMatchingProperties = LevelMatchingProperties.Create(this); } LevelMatchingProperties.ApplyValues(null, manualContentSourceNameReferenceList, newPlanetNames: manualPlanetNameReferenceList, newLevelTags: dynamicLevelTagsList, newRoutePrices: dynamicRoutePricesList, newCurrentWeathers: dynamicCurrentWeatherList); } internal void ConvertObsoleteValues() { //IL_012f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)DungeonFlow == (Object)null && (Object)(object)dungeonFlow != (Object)null) { DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonFlow is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DungeonFlow instead.", DebugType.Developer); DungeonFlow = dungeonFlow; dungeonFlow = null; } if (string.IsNullOrEmpty(DungeonName) && !string.IsNullOrEmpty(dungeonDisplayName)) { DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonDisplayName is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DungeonName instead.", DebugType.Developer); DungeonName = dungeonDisplayName; dungeonDisplayName = string.Empty; } if ((Object)(object)FirstTimeDungeonAudio == (Object)null && (Object)(object)dungeonFirstTimeAudio != (Object)null) { DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonFirstTimeAudio is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.FirstTimeDungeonAudio instead.", DebugType.Developer); FirstTimeDungeonAudio = dungeonFirstTimeAudio; dungeonFirstTimeAudio = null; } if (dungeonSizeLerpPercentage != 1f) { DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonSizeLerpPercentage is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DynamicDungeonSizeLerpRate instead.", DebugType.Developer); } if (dungeonSizeMax != 1f || dungeonSizeMin != 1f) { DebugHelper.LogWarning("ExtendedDungeonFlow.dungeonSizeMin and ExtendedDungeonFlow.dungeonSizeMax are Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.DynamicSungeonSizeMinMax instead.", DebugType.Developer); DynamicDungeonSizeMinMax = new Vector2(dungeonSizeMin, dungeonSizeMax); } if (!string.IsNullOrEmpty(contentSourceName)) { DebugHelper.LogWarning("ExtendedDungeonFlow.contentSourceName is Obsolete and will be removed in following releases, Please use ExtendedMod.AuthorName instead.", DebugType.Developer); } if ((Object)(object)LevelMatchingProperties == (Object)null && (dynamicLevelTagsList.Count > 0 || dynamicRoutePricesList.Count > 0 || dynamicCurrentWeatherList.Count > 0 || manualContentSourceNameReferenceList.Count > 0 || manualContentSourceNameReferenceList.Count > 0)) { DebugHelper.LogWarning("ExtendedDungeonFlow dynamic and manual match reference lists are Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.LevelMatchingProperties instead.", DebugType.Developer); TryCreateMatchingProperties(); } if (enableDynamicDungeonSizeRestriction || IsDynamicDungeonSizeRestrictionEnabled != enableDynamicDungeonSizeRestriction) { DebugHelper.LogWarning("ExtendedDungeonFlow.enableDynamicDungeonSizeRestriction Is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.IsDynamicDungeonRestrictionEnabled instead.", DebugType.Developer); IsDynamicDungeonSizeRestrictionEnabled = enableDynamicDungeonSizeRestriction; } if (!generateAutomaticConfigurationOptions || GenerateAutomaticConfigurationOptions != generateAutomaticConfigurationOptions) { DebugHelper.LogWarning("ExtendedDungeonFlow.generateAutomaticConfigurationOptions Is Obsolete and will be removed in following releases, Please use ExtendedDungeonFlow.GenerateAutomaticConfigurationOptions instead.", DebugType.Developer); GenerateAutomaticConfigurationOptions = generateAutomaticConfigurationOptions; } } } [Serializable] public class GlobalPropCountOverride { public int globalPropID; [Range(0f, 1f)] public float globalPropCountScaleRate = 0f; } [Serializable] public class DungeonEvents { public ExtendedEvent<RoundManager> onBeforeDungeonGenerate = new ExtendedEvent<RoundManager>(); public ExtendedEvent onShipLand = new ExtendedEvent(); public ExtendedEvent onShipLeave = new ExtendedEvent(); public ExtendedEvent<List<GameObject>> onSpawnedSyncedObjects = new ExtendedEvent<List<GameObject>>(); public ExtendedEvent<List<GameObject>> onSpawnedMapObjects = new ExtendedEvent<List<GameObject>>(); public ExtendedEvent<List<GrabbableObject>> onSpawnedScrapObjects = new ExtendedEvent<List<GrabbableObject>>(); public ExtendedEvent<(EnemyVent, EnemyAI)> onEnemySpawnedFromVent = new ExtendedEvent<(EnemyVent, EnemyAI)>(); public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerEnterDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>(); public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerExitDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>(); public ExtendedEvent<bool> onPowerSwitchToggle = new ExtendedEvent<bool>(); public ExtendedEvent<LungProp> onApparatusTaken = new ExtendedEvent<LungProp>(); } [CreateAssetMenu(fileName = "ExtendedEnemyType", menuName = "Lethal Level Loader/Extended Content/ExtendedEnemyType", order = 24)] public class ExtendedEnemyType : ExtendedContent { [field: Header("General Settings")] [field: SerializeField] public EnemyType EnemyType { get; set; } [field: SerializeField] public string EnemyDisplayName { get; set; } [field: Space(5f)] [field: Header("Dynamic Injection Matching Settings")] [field: SerializeField] public LevelMatchingProperties OutsideLevelMatchingProperties { get; set; } [field: SerializeField] public LevelMatchingProperties DaytimeLevelMatchingProperties { get; set; } [field: SerializeField] public LevelMatchingProperties InsideLevelMatchingProperties { get; set; } [field: SerializeField] public DungeonMatchingProperties InsideDungeonMatchingProperties { get; set; } [field: Space(5f)] [field: Header("Terminal Bestiary Override Settings")] [field: SerializeField] [field: TextArea(2, 20)] public string InfoNodeDescription { get; set; } = string.Empty; [field: SerializeField] public VideoClip InfoNodeVideoClip { get; set; } public ScanNodeProperties ScanNodeProperties { get; internal set; } public int EnemyID { get; internal set; } public TerminalNode EnemyInfoNode { get; internal set; } public static ExtendedEnemyType Create(EnemyType enemyType, ExtendedMod extendedMod, ContentType contentType) { ExtendedEnemyType extendedEnemyType = ScriptableObject.CreateInstance<ExtendedEnemyType>(); extendedEnemyType.EnemyType = enemyType; ((Object)extendedEnemyType).name = enemyType.enemyName.SkipToLetters().RemoveWhitespace() + "ExtendedEnemyType"; extendedEnemyType.ContentType = contentType; extendedMod.RegisterExtendedContent(extendedEnemyType); extendedEnemyType.TryCreateMatchingProperties(); return extendedEnemyType; } public void Initalize() { DebugHelper.Log("Initializing Custom Enemy: " + EnemyType.enemyName, DebugType.Developer); TryCreateMatchingProperties(); } internal override void TryCreateMatchingProperties() { if ((Object)(object)InsideLevelMatchingProperties == (Object)null) { InsideLevelMatchingProperties = LevelMatchingProperties.Create(this); } if ((Object)(object)InsideDungeonMatchingProperties == (Object)null) { InsideDungeonMatchingProperties = DungeonMatchingProperties.Create(this); } if ((Object)(object)OutsideLevelMatchingProperties == (Object)null) { OutsideLevelMatchingProperties = LevelMatchingProperties.Create(this); } if ((Object)(object)DaytimeLevelMatchingProperties == (Object)null) { DaytimeLevelMatchingProperties = LevelMatchingProperties.Create(this); } } } [CreateAssetMenu(fileName = "ExtendedFootstepSurface", menuName = "Lethal Level Loader/Extended Content/ExtendedFootstepSurface", order = 27)] public class ExtendedFootstepSurface : ExtendedContent { public FootstepSurface footstepSurface; public List<Material> associatedMaterials; public List<GameObject> associatedGameObjects; internal int arrayIndex; } [CreateAssetMenu(fileName = "ExtendedItem", menuName = "Lethal Level Loader/Extended Content/ExtendedItem", order = 23)] public class ExtendedItem : ExtendedContent { [field: Header("General Settings")] [field: SerializeField] public Item Item { get; set; } [field: SerializeField] public string PluralisedItemName { get; set; } = string.Empty; [field: SerializeField] public bool IsBuyableItem { get; set; } [field: Space(5f)] [field: Header("Dynamic Injection Matching Settings")] [field: SerializeField] public LevelMatchingProperties LevelMatchingProperties { get; set; } [field: SerializeField] public DungeonMatchingProperties DungeonMatchingProperties { get; set; } [field: Space(5f)] [field: Header("Terminal Store & Info Override Settings")] [field: SerializeField] public string OverrideInfoNodeDescription { get; set; } = string.Empty; [field: SerializeField] public string OverrideBuyNodeDescription { get; set; } = string.Empty; [field: SerializeField] public string OverrideBuyConfirmNodeDescription { get; set; } = string.Empty; public TerminalNode BuyNode { get; internal set; } public TerminalNode BuyConfirmNode { get; internal set; } public TerminalNode BuyInfoNode { get; internal set; } public int CreditsWorth { get { if ((Object)(object)BuyNode != (Object)null && (Object)(object)BuyConfirmNode != (Object)null) { BuyNode.itemCost = Item.creditsWorth; BuyConfirmNode.itemCost = Item.creditsWorth; } else { Debug.LogWarning((object)"BuyNode And/Or BuyConfirm Node Missing!"); } return Item.creditsWorth; } set { if (value >= 0) { if ((Object)(object)BuyNode != (Object)null && (Object)(object)BuyConfirmNode != (Object)null) { BuyNode.itemCost = value; BuyConfirmNode.itemCost = value; } else { Debug.LogWarning((object)"BuyNode And/Or BuyConfirm Node Missing!"); } Item.creditsWorth = value; } } } public static ExtendedItem Create(Item newItem, ExtendedMod extendedMod, ContentType contentType) { ExtendedItem extendedItem = ScriptableObject.CreateInstance<ExtendedItem>(); extendedItem.Item = newItem; ((Object)extendedItem).name = newItem.itemName.SkipToLetters().RemoveWhitespace() + "ExtendedItem"; extendedItem.ContentType = contentType; extendedMod.RegisterExtendedContent(extendedItem); extendedItem.TryCreateMatchingProperties(); return extendedItem; } public void Initialize() { DebugHelper.Log("Initializing Custom Item: " + Item.itemName + ". Is Buyable: " + IsBuyableItem + ". Is Scrap: " + Item.isScrap, DebugType.Developer); TryCreateMatchingProperties(); Patches.StartOfRound.allItemsList.itemsList.Add(Item); if (IsBuyableItem) { TerminalManager.CreateItemTerminalData(this); } } internal override void TryCreateMatchingProperties() { if ((Object)(object)LevelMatchingProperties == (Object)null) { LevelMatchingProperties = LevelMatchingProperties.Create(this); } if ((Object)(object)DungeonMatchingProperties == (Object)null) { DungeonMatchingProperties = DungeonMatchingProperties.Create(this); } } public void SetLevelMatchingProperties(LevelMatchingProperties newLevelMatchingProperties) { if ((Object)(object)Plugin.Instance != (Object)null) { Debug.LogError((object)"SetLevelMatchingProperties() Should Only Be Used In Editor!"); } LevelMatchingProperties = newLevelMatchingProperties; } } [CreateAssetMenu(fileName = "ExtendedLevel", menuName = "Lethal Level Loader/Extended Content/ExtendedLevel", order = 20)] public class ExtendedLevel : ExtendedContent { [Space(5f)] [SerializeField] private int routePrice = 0; [Space(25f)] [Header("Obsolete (Legacy Fields, Will Be Removed In The Future)")] [Obsolete] public SelectableLevel selectableLevel; [Obsolete] [Space(5f)] public string contentSourceName = string.Empty; [Obsolete] [Space(5f)] public List<string> levelTags = new List<string>(); [field: Header("General Settings")] [field: SerializeField] public SelectableLevel SelectableLevel { get; set; } [field: Header("Extended Feature Settings")] [field: SerializeField] public bool OverrideDynamicRiskLevelAssignment { get; set; } = false; [field: Space(5f)] [field: SerializeField] public GameObject OverrideQuicksandPrefab { get; set; } [field: Space(5f)] [field: SerializeField] public bool IsRouteHidden { get; set; } = false; [field: SerializeField] public bool IsRouteLocked { get; set; } = false; [field: SerializeField] public string LockedRouteNodeText { get; set; } = string.Empty; [field: Space(5f)] [field: SerializeField] public AnimationClip ShipFlyToMoonClip { get; set; } [field: SerializeField] public AnimationClip ShipFlyFromMoonClip { get; set; } [field: Space(5f)] [field: SerializeField] public List<StringWithRarity> SceneSelections { get; set; } = new List<StringWithRarity>(); [field: Space(5f)] [field: Header("Terminal Route Override Settings")] [field: SerializeField] [field: TextArea(2, 20)] public string OverrideInfoNodeDescription { get; set; } = string.Empty; [field: SerializeField] [field: TextArea(2, 20)] public string OverrideRouteNodeDescription { get; set; } = string.Empty; [field: SerializeField] [field: TextArea(2, 20)] public string OverrideRouteConfirmNodeDescription { get; set; } = string.Empty; [field: Space(10f)] [field: Header("Misc. Settings")] [field: Space(5f)] [field: SerializeField] public bool GenerateAutomaticConfigurationOptions { get; set; } = true; public int RoutePrice { get { if ((Object)(object)RouteNode != (Object)null) { routePrice = RouteNode.itemCost; RouteConfirmNode.itemCost = routePrice; return RouteNode.itemCost; } DebugHelper.LogWarning("routeNode Is Missing! Using internal value!", DebugType.Developer); return routePrice; } set { if ((Object)(object)RouteNode != (Object)null && (Object)(object)RouteConfirmNode != (Object)null) { RouteNode.itemCost = value; RouteConfirmNode.itemCost = value; } else { DebugHelper.LogWarning("routeNode Is Missing! Only setting internal value!", DebugType.Developer); } routePrice = value; } } public string NumberlessPlanetName => GetNumberlessPlanetName(SelectableLevel); public int CalculatedDifficultyRating => LevelManager.CalculateExtendedLevelDifficultyRating(this); public bool IsCurrentLevel => (Object)(object)LevelManager.CurrentExtendedLevel == (Object)(object)this; public bool IsLevelLoaded { get { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) Scene sceneByName = SceneManager.GetSceneByName(SelectableLevel.sceneName); return ((Scene)(ref sceneByName)).isLoaded; } } [HideInInspector] public LevelEvents LevelEvents { get; internal set; } = new LevelEvents(); public TerminalNode RouteNode { get; internal set; } public TerminalNode RouteConfirmNode { get; internal set; } public TerminalNode InfoNode { get; internal set; } public List<ExtendedWeatherEffect> EnabledExtendedWeatherEffects { get; set; } = new List<ExtendedWeatherEffect>(); public ExtendedWeatherEffect CurrentExtendedWeatherEffect { get; set; } internal static ExtendedLevel Create(SelectableLevel newSelectableLevel) { ExtendedLevel extendedLevel = ScriptableObject.CreateInstance<ExtendedLevel>(); extendedLevel.SelectableLevel = newSelectableLevel; return extendedLevel; } internal void Initialize(string newContentSourceName, bool generateTerminalAssets) { bool flag = false; foreach (StringWithRarity sceneSelection in SceneSelections) { if (sceneSelection.Name == SelectableLevel.sceneName) { flag = true; } } if (!flag) { StringWithRarity item = new StringWithRarity(SelectableLevel.sceneName, 300); SceneSelections.Add(item); } foreach (StringWithRarity item2 in new List<StringWithRarity>(SceneSelections)) { if (!PatchedContent.AllLevelSceneNames.Contains(item2.Name)) { DebugHelper.LogWarning("Removing SceneSelection From: " + SelectableLevel.PlanetName + " As SceneName: " + item2.Name + " Is Not Loaded!", DebugType.Developer); SceneSelections.Remove(item2); } } if ((Object)(object)ShipFlyToMoonClip == (Object)null) { ShipFlyToMoonClip = LevelLoader.defaultShipFlyToMoonClip; } if ((Object)(object)ShipFlyFromMoonClip == (Object)null) { ShipFlyFromMoonClip = LevelLoader.defaultShipFlyFromMoonClip; } if ((Object)(object)OverrideQuicksandPrefab == (Object)null) { OverrideQuicksandPrefab = LevelLoader.defaultQuicksandPrefab; } if (base.ContentType == ContentType.Custom) { ((Object)this).name = NumberlessPlanetName.StripSpecialCharacters() + "ExtendedLevel"; ((Object)SelectableLevel).name = NumberlessPlanetName.StripSpecialCharacters() + "Level"; if (generateTerminalAssets) { TerminalManager.CreateLevelTerminalData(this, routePrice); } } if (base.ContentType == ContentType.Vanilla) { GetVanillaInfoNode(); } SetExtendedDungeonFlowMatches(); } internal void ConvertObsoleteValues() { if (levelTags.Count > 0 && base.ContentTags.Count == 0) { DebugHelper.LogWarning("ExtendedLevel.levelTags Is Obsolete and will be removed in following releases, Please use .ContentTags instead.", DebugType.Developer); foreach (ContentTag item in ContentTagManager.CreateNewContentTags(levelTags)) { base.ContentTags.Add(item); } } levelTags.Clear(); if ((Object)(object)SelectableLevel == (Object)null && (Object)(object)selectableLevel != (Object)null) { DebugHelper.LogWarning("ExtendedLevel.selectableLevel Is Obsolete and will be removed in following releases, Please use .SelectableLevel instead.", DebugType.Developer); SelectableLevel = selectableLevel; } if (!string.IsNullOrEmpty(contentSourceName)) { DebugHelper.LogWarning("ExtendedLevel.contentSourceName is Obsolete and will be removed in following releases, Please use ExtendedMod.AuthorName instead.", DebugType.Developer); } } internal static string GetNumberlessPlanetName(SelectableLevel selectableLevel) { if ((Object)(object)selectableLevel != (Object)null) { return new string(selectableLevel.PlanetName.SkipWhile((char c) => !char.IsLetter(c)).ToArray()); } return string.Empty; } internal void SetLevelID() { if (base.ContentType == ContentType.Custom) { SelectableLevel.levelID = PatchedContent.ExtendedLevels.IndexOf(this); if ((Object)(object)RouteNode != (Object)null) { RouteNode.displayPlanetInfo = SelectableLevel.levelID; } if ((Object)(object)RouteConfirmNode != (Object)null) { RouteConfirmNode.buyRerouteToMoon = SelectableLevel.levelID; } } } internal void SetExtendedDungeonFlowMatches() { IntWithRarity[] dungeonFlowTypes = SelectableLevel.dungeonFlowTypes; foreach (IntWithRarity val in dungeonFlowTypes) { if (DungeonManager.TryGetExtendedDungeonFlow(Patches.RoundManager.dungeonFlowTypes[val.id].dungeonFlow, out var returnExtendedDungeonFlow)) { returnExtendedDungeonFlow.LevelMatchingProperties.planetNames.Add(new StringWithRarity(NumberlessPlanetName, val.rarity)); } } if (!(SelectableLevel.sceneName == "Level4March")) { return; } IndoorMapType[] dungeonFlowTypes2 = Patches.RoundManager.dungeonFlowTypes; foreach (IndoorMapType val2 in dungeonFlowTypes2) { if (((Object)val2.dungeonFlow).name == "Level1Flow3Exits" && DungeonManager.TryGetExtendedDungeonFlow(val2.dungeonFlow, out var returnExtendedDungeonFlow2)) { returnExtendedDungeonFlow2.LevelMatchingProperties.planetNames.Add(new StringWithRarity(NumberlessPlanetName, 300)); } } } internal void GetVanillaInfoNode() { CompatibleNoun[] compatibleNouns = TerminalManager.routeInfoKeyword.compatibleNouns; foreach (CompatibleNoun val in compatibleNouns) { if (val.noun.word == NumberlessPlanetName.ToLower()) { InfoNode = val.result; break; } } } public void ForceSetRoutePrice(int newValue) { if ((Object)(object)Plugin.Instance != (Object)null) { Debug.LogWarning((object)"ForceSetRoutePrice Should Only Be Used In Editor! Consider Using RoutePrice Property To Sync TerminalNode's With New Value."); } routePrice = newValue; } } [Serializable] public class LevelEvents { public ExtendedEvent onLevelLoaded = new ExtendedEvent(); public ExtendedEvent onShipLand = new ExtendedEvent(); public ExtendedEvent onShipLeave = new ExtendedEvent(); public ExtendedEvent<EnemyAI> onDaytimeEnemySpawn = new ExtendedEvent<EnemyAI>(); public ExtendedEvent<EnemyAI> onNighttimeEnemySpawn = new ExtendedEvent<EnemyAI>(); public ExtendedEvent<StoryLog> onStoryLogCollected = new ExtendedEvent<StoryLog>(); public ExtendedEvent<LungProp> onApparatusTaken = new ExtendedEvent<LungProp>(); public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerEnterDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>(); public ExtendedEvent<(EntranceTeleport, PlayerControllerB)> onPlayerExitDungeon = new ExtendedEvent<(EntranceTeleport, PlayerControllerB)>(); public ExtendedEvent<bool> onPowerSwitchToggle = new ExtendedEvent<bool>(); public ExtendedEvent<DayMode> onDayModeToggle = new ExtendedEvent<DayMode>(); } public enum ModMergeSetting { MatchingAuthorName, MatchingModName, Disabled } [CreateAssetMenu(fileName = "ExtendedMod", menuName = "Lethal Level Loader/ExtendedMod", order = 30)] public class ExtendedMod : ScriptableObject { [field: SerializeField] public string ModName { get; internal set; } = "Unspecified"; [field: SerializeField] public string AuthorName { get; internal set; } = "Unknown"; public List<string> ModNameAliases { get; internal set; } = new List<string>(); [field: SerializeField] public ModMergeSetting ModMergeSetting { get; internal set; } = ModMergeSetting.MatchingAuthorName; [field: SerializeField] public List<ExtendedLevel> ExtendedLevels { get; private set; } = new List<ExtendedLevel>(); [field: SerializeField] public List<ExtendedDungeonFlow> ExtendedDungeonFlows { get; private set; } = new List<ExtendedDungeonFlow>(); [field: SerializeField] public List<ExtendedItem> ExtendedItems { get; private set; } = new List<ExtendedItem>(); [field: SerializeField] public List<ExtendedEnemyType> ExtendedEnemyTypes { get; private set; } = new List<ExtendedEnemyType>(); [field: SerializeField] public List<ExtendedWeatherEffect> ExtendedWeatherEffects { get; private set; } = new List<ExtendedWeatherEffect>(); [field: SerializeField] public List<ExtendedFootstepSurface> ExtendedFootstepSurfaces { get; private set; } = new List<ExtendedFootstepSurface>(); [field: SerializeField] public List<ExtendedStoryLog> ExtendedStoryLogs { get; private set; } = new List<ExtendedStoryLog>(); public List<ExtendedContent> ExtendedContents { get { List<ExtendedContent> list = new List<ExtendedContent>(); foreach (ExtendedLevel extendedLevel in ExtendedLevels) { list.Add(extendedLevel); } foreach (ExtendedDungeonFlow extendedDungeonFlow in ExtendedDungeonFlows) { list.Add(extendedDungeonFlow); } foreach (ExtendedItem extendedItem in ExtendedItems) { list.Add(extendedItem); } foreach (ExtendedEnemyType extendedEnemyType in ExtendedEnemyTypes) { list.Add(extendedEnemyType); } foreach (ExtendedWeatherEffect extendedWeatherEffect in ExtendedWeatherEffects) { list.Add(extendedWeatherEffect); } foreach (ExtendedFootstepSurface extendedFootstepSurface in ExtendedFootstepSurfaces) { list.Add(extendedFootstepSurface); } return list; } } internal static ExtendedMod Create(string modName) { ExtendedMod extendedMod = ScriptableObject.CreateInstance<ExtendedMod>(); extendedMod.ModName = modName; ((Object)extendedMod).name = modName.Sanitized() + "Mod"; DebugHelper.Log("Created New ExtendedMod: " + extendedMod.ModName, DebugType.Developer); return extendedMod; } public static ExtendedMod Create(string modName, string authorName) { ExtendedMod extendedMod = ScriptableObject.CreateInstance<ExtendedMod>(); extendedMod.ModName = modName; ((Object)extendedMod).name = modName.SkipToLetters().RemoveWhitespace() + "Mod"; extendedMod.AuthorName = authorName; if ((Object)(object)Plugin.Instance != (Object)null) { DebugHelper.Log("Created New ExtendedMod: " + extendedMod.ModName + " by " + authorName, DebugType.Developer); } return extendedMod; } public static ExtendedMod Create(string modName, string authorName, ExtendedContent[] extendedContents) { ExtendedMod extendedMod = ScriptableObject.CreateInstance<ExtendedMod>(); extendedMod.ModName = modName; ((Object)extendedMod).name = modName.SkipToLetters().RemoveWhitespace() + "Mod"; extendedMod.AuthorName = authorName; foreach (ExtendedContent newExtendedContent in extendedContents) { extendedMod.RegisterExtendedContent(newExtendedContent); } if ((Object)(object)Plugin.Instance != (Object)null) { DebugHelper.Log("Created New ExtendedMod: " + extendedMod.ModName + " by " + authorName, DebugType.Developer); } return extendedMod; } internal void RegisterExtendedContent(ExtendedContent newExtendedContent) { if ((Object)(object)newExtendedContent != (Object)null) { if (!ExtendedContents.Contains(newExtendedContent)) { if (newExtendedContent is ExtendedLevel extendedLevel) { RegisterExtendedContent(extendedLevel); return; } if (newExtendedContent is ExtendedDungeonFlow extendedDungeonFlow) { RegisterExtendedContent(extendedDungeonFlow); return; } if (newExtendedContent is ExtendedItem extendedItem) { RegisterExtendedContent(extendedItem); return; } if (newExtendedContent is ExtendedEnemyType extendedEnemyType) { RegisterExtendedContent(extendedEnemyType); return; } if (newExtendedContent is ExtendedWeatherEffect extendedWeatherEffect) { RegisterExtendedContent(extendedWeatherEffect); return; } if (newExtendedContent is ExtendedFootstepSurface extendedFootstepSurface) { RegisterExtendedContent(extendedFootstepSurface); return; } if (newExtendedContent is ExtendedStoryLog extendedStoryLog) { RegisterExtendedContent(extendedStoryLog); return; } throw new ArgumentException("newExtendedContent", ((Object)newExtendedContent).name + " (" + ((object)newExtendedContent).GetType().Name + ") Could Not Be Registered To ExtendedMod: " + ModName + " Due To Unimplemented Registration Check!"); } throw new ArgumentException("newExtendedContent", ((Object)newExtendedContent).name + " (" + ((object)newExtendedContent).GetType().Name + ") Could Not Be Registered To ExtendedMod: " + ModName + " Due To Already Being Registered To This Mod!"); } throw new ArgumentNullException("newExtendedContent", "Null ExtendedContent Could Not Be Registered To ExtendedMod: " + ModName + " Due To Failed Validation Check!"); } internal void RegisterExtendedContent(ExtendedLevel extendedLevel) { extendedLevel.ConvertObsoleteValues(); TryThrowInvalidContentException(extendedLevel, Validators.ValidateExtendedContent(extendedLevel)); ExtendedLevels.Add(extendedLevel); extendedLevel.ContentTags.Add(ContentTag.Create("Custom")); extendedLevel.ExtendedMod = this; } internal void RegisterExtendedContent(ExtendedDungeonFlow extendedDungeonFlow) { extendedDungeonFlow.ConvertObsoleteValues(); TryThrowInvalidContentException(extendedDungeonFlow, Validators.ValidateExtendedContent(extendedDungeonFlow)); ExtendedDungeonFlows.Add(extendedDungeonFlow); extendedDungeonFlow.ContentTags.Add(ContentTag.Create("Custom")); extendedDungeonFlow.ExtendedMod = this; } internal void RegisterExtendedContent(ExtendedItem extendedItem) { TryThrowInvalidContentException(extendedItem, Validators.ValidateExtendedContent(extendedItem)); ExtendedItems.Add(extendedItem); extendedItem.ContentTags.Add(ContentTag.Create("Custom")); extendedItem.ExtendedMod = this; } internal void RegisterExtendedContent(ExtendedEnemyType extendedEnemyType) { TryThrowInvalidContentException(extendedEnemyType, Validators.ValidateExtendedContent(extendedEnemyType)); ExtendedEnemyTypes.Add(extendedEnemyType); extendedEnemyType.ContentTags.Add(ContentTag.Create("Custom")); extendedEnemyType.ExtendedMod = this; } internal void RegisterExtendedContent(ExtendedWeatherEffect extendedWeatherEffect) { TryThrowInvalidContentException(extendedWeatherEffect, Validators.ValidateExtendedContent(extendedWeatherEffect)); ExtendedWeatherEffects.Add(extendedWeatherEffect); extendedWeatherEffect.ContentTags.Add(ContentTag.Create("Custom")); extendedWeatherEffect.ExtendedMod = this; } internal void RegisterExtendedContent(ExtendedFootstepSurface extendedFootstepSurface) { TryThrowInvalidContentException(extendedFootstepSurface, Validators.ValidateExtendedContent(extendedFootstepSurface)); ExtendedFootstepSurfaces.Add(extendedFootstepSurface); extendedFootstepSurface.ContentTags.Add(ContentTag.Create("Custom")); extendedFootstepSurface.ExtendedMod = this; } internal void RegisterExtendedContent(ExtendedStoryLog extendedStoryLog) { TryThrowInvalidContentException(extendedStoryLog, Validators.ValidateExtendedContent(extendedStoryLog)); ExtendedStoryLogs.Add(extendedStoryLog); extendedStoryLog.ContentTags.Add(ContentTag.Create("Custom")); extendedStoryLog.ExtendedMod = this; } internal void TryThrowInvalidContentException(ExtendedContent extendedContent, (bool, string) result) { if (!result.Item1) { if ((Object)(object)extendedContent == (Object)null) { throw new ArgumentNullException("extendedContent", "Null ExtendedContent Could Not Be Registered To ExtendedMod: " + ModName + " Due To Failed Validation Check! " + result.Item2); } throw new ArgumentException("extendedContent", ((Object)extendedContent).name + " (" + ((object)extendedContent).GetType().Name + ") Could Not Be Registered To ExtendedMod: " + ModName + " Due To Failed Validation Check! " + result.Item2); } } internal void UnregisterExtendedContent(ExtendedContent currentExtendedContent) { if (currentExtendedContent is ExtendedLevel item) { ExtendedLevels.Remove(item); } else if (currentExtendedContent is ExtendedDungeonFlow item2) { ExtendedDungeonFlows.Remove(item2); } else if (currentExtendedContent is ExtendedItem item3) { ExtendedItems.Remove(item3); } currentExtendedContent.ExtendedMod = null; DebugHelper.LogWarning("Unregistered ExtendedContent: " + ((Object)currentExtendedContent).name + " In ExtendedMod: " + ModName, DebugType.Developer); } internal void UnregisterAllExtendedContent() { ExtendedLevels.Clear(); ExtendedDungeonFlows.Clear(); ExtendedItems.Clear(); ExtendedEnemyTypes.Clear(); ExtendedWeatherEffects.Clear(); ExtendedFootstepSurfaces.Clear(); } internal void SortRegisteredContent() { ExtendedDungeonFlows.Sort((ExtendedDungeonFlow s1, ExtendedDungeonFlow s2) => ((Object)s1).name.CompareTo(((Object)s2).name)); ExtendedItems.Sort((ExtendedItem s1, ExtendedItem s2) => ((Object)s1).name.CompareTo(((Object)s2).name)); ExtendedEnemyTypes.Sort((ExtendedEnemyType s1, ExtendedEnemyType s2) => ((Object)s1).name.CompareTo(((Object)s2).name)); ExtendedWeatherEffects.Sort((ExtendedWeatherEffect s1, ExtendedWeatherEffect s2) => ((Object)s1).name.CompareTo(((Object)s2).name)); ExtendedFootstepSurfaces.Sort((ExtendedFootstepSurface s1, ExtendedFootstepSurface s2) => ((Object)s1).name.CompareTo(((Object)s2).name)); } internal void Example() { AssetBundle val = null; ExtendedDungeonFlow extendedDungeonFlow = val.LoadAsset<ExtendedDungeonFlow>("Assets/CoolDungeonFlow"); ExtendedEnemyType extendedEnemyType = val.LoadAsset<ExtendedEnemyType>("Assets/Ghost"); ExtendedMod extendedMod = Create("BatbysMod", "IAmBatby", new ExtendedContent[2] { extendedDungeonFlow, extendedEnemyType }); PatchedContent.RegisterExtendedMod(extendedMod); } } [CreateAssetMenu(fileName = "ExtendedStoryLog", menuName = "Lethal Level Loader/Extended Content/ExtendedStoryLog", order = 26)] public class ExtendedStoryLog : ExtendedContent { public string sceneName = string.Empty; public int storyLogID; [Space(5f)] public string terminalKeywordNoun = string.Empty; [Space(5f)] public string storyLogTitle = string.Empty; [TextArea] public string storyLogDescription = string.Empty; [HideInInspector] internal int newStoryLogID; } [CreateAssetMenu(fileName = "ExtendedWeatherEffect", menuName = "Lethal Level Loader/Extended Content/ExtendedWeatherEffect", order = 25)] public class ExtendedWeatherEffect : ExtendedContent { public ContentType contentType; [field: Header("General Settings")] [field: SerializeField] public LevelWeatherType BaseWeatherType { get; set; } = (LevelWeatherType)(-1); [field: SerializeField] public string WeatherDisplayName { get; set; } = string.Empty; [field: SerializeField] public GameObject WorldObject { get; set; } [field: SerializeField] public GameObject GlobalObject { get; set; } internal static ExtendedWeatherEffect Create(LevelWeatherType levelWeatherType, WeatherEffect weatherEffect, string weatherDisplayName, ContentType newContentType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return Create(levelWeatherType, weatherEffect.effectObject, weatherEffect.effectPermanentObject, weatherDisplayName, newContentType); } internal static ExtendedWeatherEffect Create(LevelWeatherType levelWeatherType, GameObject worldObject, GameObject globalObject, string newWeatherDisplayName, ContentType newContentType) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) ExtendedWeatherEffect extendedWeatherEffect = ScriptableObject.CreateInstance<ExtendedWeatherEffect>(); extendedWeatherEffect.WeatherDisplayName = newWeatherDisplayName; ((Object)extendedWeatherEffect).name = extendedWeatherEffect.WeatherDisplayName + "ExtendedWeatherEffect"; extendedWeatherEffect.BaseWeatherType = levelWeatherType; extendedWeatherEffect.WorldObject = worldObject; extendedWeatherEffect.GlobalObject = globalObject; return extendedWeatherEffect; } } public class LLLSaveFile : ModDataContainer { public int parityStepsTaken; public Dictionary<int, AllItemsListItemData> itemSaveData = new Dictionary<int, AllItemsListItemData>(); public string CurrentLevelName { get; internal set; } = string.Empty; public void Reset() { CurrentLevelName = string.Empty; parityStepsTaken = 0; itemSaveData = new Dictionary<int, AllItemsListItemData>(); } } public struct AllItemsListItemData { public string itemObjectName; public string itemName; public string modName; public string modAuthor; public int allItemsListIndex; public int modItemsListIndex; public int itemNameDuplicateIndex; public bool isScrap; public bool saveItemVariable; public AllItemsListItemData(string newItemObjectName, string newItemName, string newModName, string newModAuthor, int newAllItemsListIndex, int newModItemsListIndex, int newItemNameDuplicateIndex, bool newIsScrap, bool newSaveItemVariable) { itemObjectName = newItemObjectName; itemName = newItemName; modName = newModName; modAuthor = newModAuthor; allItemsListIndex = newAllItemsListIndex; modItemsListIndex = newModItemsListIndex; itemNameDuplicateIndex = newItemNameDuplicateIndex; isScrap = newIsScrap; saveItemVariable = newSaveItemVariable; } } [CreateAssetMenu(fileName = "ContentTag", menuName = "Lethal Level Loader/Utility/ContentTag", order = 11)] public class ContentTag : ScriptableObject { public string contentTagName; public Color contentTagColor; public static ContentTag Create(string tag, Color color) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) ContentTag contentTag = ScriptableObject.CreateInstance<ContentTag>(); contentTag.contentTagName = tag; contentTag.contentTagColor = color; ((Object)contentTag).name = tag + "ContentTag"; return contentTag; } public static ContentTag Create(string tag) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return Create(tag, Color.white); } } [CreateAssetMenu(fileName = "DungeonMatchingProperties", menuName = "Lethal Level Loader/Utility/DungeonMatchingProperties", order = 13)] public class DungeonMatchingProperties : MatchingProperties { [Space(5f)] public List<StringWithRarity> dungeonTags = new List<StringWithRarity>(); [Space(5f)] public List<StringWithRarity> dungeonNames = new List<StringWithRarity>(); public new static DungeonMatchingProperties Create(ExtendedContent extendedContent) { DungeonMatchingProperties dungeonMatchingProperties = ScriptableObject.CreateInstance<DungeonMatchingProperties>(); ((Object)dungeonMatchingProperties).name = ((Object)extendedContent).name + "DungeonMatchingProperties"; return dungeonMatchingProperties; } public int GetDynamicRarity(ExtendedDungeonFlow extendedDungeonFlow) { int currentValue = 0; MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedTags(extendedDungeonFlow.ContentTags, dungeonNames), ((Object)extendedDungeonFlow).name, "Content Tags"); MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(extendedDungeonFlow.AuthorName, authorNames), ((Object)extendedDungeonFlow).name, "Author Name"); MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedStrings(extendedDungeonFlow.ExtendedMod.ModNameAliases, modNames), ((Object)extendedDungeonFlow).name, "Mod Name Name"); MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(((Object)extendedDungeonFlow.DungeonFlow).name, dungeonNames), ((Object)extendedDungeonFlow).name, "Dungeon Name"); return currentValue; } public void ApplyValues(List<StringWithRarity> newModNames = null, List<StringWithRarity> newAuthorNames = null, List<StringWithRarity> newDungeonTags = null, List<StringWithRarity> newDungeonNames = null) { if (newModNames != null && newModNames.Count != 0) { modNames = new List<StringWithRarity>(newModNames); } if (newAuthorNames != null && newAuthorNames.Count != 0) { authorNames = new List<StringWithRarity>(newAuthorNames); } if (newDungeonTags != null && newDungeonTags.Count != 0) { dungeonTags = new List<StringWithRarity>(newDungeonTags); } if (newDungeonNames != null && newDungeonNames.Count != 0) { dungeonNames = new List<StringWithRarity>(newDungeonNames); } } } [CreateAssetMenu(fileName = "LevelMatchingProperties", menuName = "Lethal Level Loader/Utility/LevelMatchingProperties", order = 12)] public class LevelMatchingProperties : MatchingProperties { [Space(5f)] public List<StringWithRarity> levelTags = new List<StringWithRarity>(); [Space(5f)] public List<Vector2WithRarity> currentRoutePrice = new List<Vector2WithRarity>(); [Space(5f)] public List<StringWithRarity> currentWeather = new List<StringWithRarity>(); [Space(5f)] public List<StringWithRarity> planetNames = new List<StringWithRarity>(); public new static LevelMatchingProperties Create(ExtendedContent extendedContent) { LevelMatchingProperties levelMatchingProperties = ScriptableObject.CreateInstance<LevelMatchingProperties>(); ((Object)levelMatchingProperties).name = ((Object)extendedContent).name + "LevelMatchingProperties"; return levelMatchingProperties; } public int GetDynamicRarity(ExtendedLevel extendedLevel) { int currentValue = 0; MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedTags(extendedLevel.ContentTags, levelTags), ((Object)extendedLevel).name, "Content Tags"); MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(extendedLevel.AuthorName, authorNames), ((Object)extendedLevel).name, "Author Name"); MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedStrings(extendedLevel.ExtendedMod.ModNameAliases, modNames), ((Object)extendedLevel).name, "Mod Name"); MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingWithinRanges(extendedLevel.RoutePrice, currentRoutePrice), ((Object)extendedLevel).name, "Route Price"); MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(extendedLevel.NumberlessPlanetName, planetNames), ((Object)extendedLevel).name, "Planet Name"); MatchingProperties.UpdateRarity(ref currentValue, MatchingProperties.GetHighestRarityViaMatchingNormalizedString(((object)(LevelWeatherType)(ref extendedLevel.SelectableLevel.currentWeather)).ToString(), currentWeather), ((Object)extendedLevel).name, "Current Weather"); return currentValue; } public void ApplyValues(List<StringWithRarity> newModNames = null, List<StringWithRarity> newAuthorNames = null, List<StringWithRarity> newLevelTags = null, List<Vector2WithRarity> newRoutePrices = null, List<StringWithRarity> newCurrentWeathers = null, List<StringWithRarity> newPlanetNames = null) { if (newModNames != null && newModNames.Count != 0) { modNames = new List<StringWithRarity>(newModNames); } if (newAuthorNames != null && newAuthorNames.Count != 0) { authorNames = new List<StringWithRarity>(newAuthorNames); } if (newLevelTags != null && newLevelTags.Count != 0) { levelTags = new List<StringWithRarity>(newLevelTags); } if (newRoutePrices != null && newRoutePrices.Count != 0) { currentRoutePrice = new List<Vector2WithRarity>(newRoutePrices); } if (newCurrentWeathers != null && newCurrentWeathers.Count != 0) { currentWeather = new List<StringWithRarity>(newCurrentWeathers); } if (newPlanetNames != null && newPlanetNames.Count != 0) { planetNames = new List<StringWithRarity>(newPlanetNames); } } } public class MatchingProperties : ScriptableObject { [Space(5f)] public List<StringWithRarity> modNames = new List<StringWithRarity>(); [Space(5f)] public List<StringWithRarity> authorNames = new List<StringWithRarity>(); public static MatchingProperties Create(ExtendedContent extendedContent) { MatchingProperties matchingProperties = ScriptableObject.CreateInstance<MatchingProperties>(); ((Object)matchingProperties).name = ((Object)extendedContent).name + "MatchingProperties"; return matchingProperties; } internal static bool UpdateRarity(ref int currentValue, int newValue, string debugActionObject = null, string debugActionReason = null) { if (newValue > currentValue) { if (!string.IsNullOrEmpty(debugActionReason)) { if (!string.IsNullOrEmpty(debugActionObject)) { DebugHelper.Log("Raised Rarity Of: " + debugActionObject + " From (" + currentValue + ") To (" + newValue + ") Due To Matching " + debugActionReason, DebugType.Developer); } else { DebugHelper.Log("Raised Rarity From (" + currentValue + ") To (" + newValue + ") Due To Matching " + debugActionReason, DebugType.Developer); } } currentValue = newValue; return true; } return false; } internal static int GetHighestRarityViaMatchingWithinRanges(int comparingValue, List<Vector2WithRarity> matchingVectors) { int num = 0; foreach (Vector2WithRarity matchingVector in matchingVectors) { if (matchingVector.Rarity >= num && (float)comparingValue >= matchingVector.Min && (float)comparingValue <= matchingVector.Max) { num = matchingVector.Rarity; } } return num; } internal static int GetHighestRarityViaMatchingNormalizedString(string comparingString, List<StringWithRarity> matchingStrings) { return GetHighestRarityViaMatchingNormalizedStrings(new List<string> { comparingString }, matchingStrings); } internal static int GetHighestRarityViaMatchingNormalizedTags(List<ContentTag> comparingTags, List<StringWithRarity> matchingStrings) { List<string> comparingStrings = comparingTags.Select((ContentTag t) => t.contentTagName).ToList(); return GetHighestRarityViaMatchingNormalizedStrings(comparingStrings, matchingStrings); } internal static int GetHighestRarityViaMatchingNormalizedStrings(List<string> comparingStrings, List<StringWithRarity> matchingStrings) { int num = 0; foreach (StringWithRarity matchingString in matchingStrings) { foreach (string item in new List<string>(comparingStrings)) { if (matchingString.Rarity >= num && (matchingString.Name.Sanitized().Contains(item.Sanitized()) || item.Sanitized().Contains(matchingString.Name.Sanitized()))) { num = matchingString.Rarity; } } } return num; } } public class MoonsCataloguePage { private List<ExtendedLevelGroup> extendedLevelGroups; public List<ExtendedLevelGroup> ExtendedLevelGroups => extendedLevelGroups; public List<ExtendedLevel> ExtendedLevels { get { List<ExtendedLevel> list = new List<ExtendedLevel>(); foreach (ExtendedLevelGroup extendedLevelGroup in extendedLevelGroups) { foreach (ExtendedLevel extendedLevels in extendedLevelGroup.extendedLevelsList) { list.Add(extendedLevels); } } return list; } } public MoonsCataloguePage(List<ExtendedLevelGroup> newExtendedLevelGroupList) { extendedLevelGroups = new List<ExtendedLevelGroup>(); extendedLevelGroups.Clear(); foreach (ExtendedLevelGroup newExtendedLevelGroup in newExtendedLevelGroupList) { extendedLevelGroups.Add(new ExtendedLevelGroup(newExtendedLevelGroup.extendedLevelsList)); } } public void RebuildLevelGroups(List<ExtendedLevelGroup> newExtendedLevelGroups, int splitCount) { List<ExtendedLevel> list = new List<ExtendedLevel>(); foreach (ExtendedLevelGroup extendedLevelGroup in extendedLevelGroups) { foreach (ExtendedLevel extendedLevels in extendedLevelGroup.extendedLevelsList) { list.Add(extendedLevels); } } RebuildLevelGroups(list.ToArray(), splitCount); } public void RebuildLevelGroups(List<ExtendedLevel> newExtendedLevels, int splitCount) { RebuildLevelGroups(newExtendedLevels.ToArray(), splitCount); } public void RebuildLevelGroups(IOrderedEnumerable<ExtendedLevel> orderedExtendedLevels, int splitCount) { RebuildLevelGroups(orderedExtendedLevels.ToArray(), splitCount); } public void RebuildLevelGroups(ExtendedLevel[] newExtendedLevels, int splitCount) { extendedLevelGroups = TerminalManager.GetExtendedLevelGroups(newExtendedLevels, splitCount); } public void RefreshLevelGroups(List<ExtendedLevelGroup> newLevelGroups) { extendedLevelGroups.Clear(); foreach (ExtendedLevelGroup newLevelGroup in newLevelGroups) { if (newLevelGroup.extendedLevelsList.Count != 0) { extendedLevelGroups.Add(new ExtendedLevelGroup(newLevelGroup.extendedLevelsList)); } } } } [Serializable] public class ExtendedLevelGroup { public List<ExtendedLevel> extendedLevelsList; public int AverageCalculatedDifficulty => GetAverageCalculatedDifficulty(); public ExtendedLevelGroup(List<ExtendedLevel> newExtendedLevelsList) { extendedLevelsList = new List<ExtendedLevel>(newExtendedLevelsList); } public ExtendedLevelGroup(List<SelectableLevel> newSelectableLevelsList) { extendedLevelsList = new List<ExtendedLevel>(); foreach (SelectableLevel newSelectableLevels in newSelectableLevelsList) { extendedLevelsList.Add(LevelManager.GetExtendedLevel(newSelectableLevels)); } } public int GetAverageCalculatedDifficulty() { List<int> list = new List<int>(); foreach (ExtendedLevel extendedLevels in extendedLevelsList) { list.Add(extendedLevels.CalculatedDifficultyRating); } return (int)list.Average(); } } public static class PatchedContent { public static ExtendedMod VanillaMod { get; internal set; } public static List<string> AllLevelSceneNames { get; internal set; } = new List<string>(); public static List<ExtendedMod> ExtendedMods { get; internal set; } = new List<ExtendedMod>(); public static List<ExtendedLevel> ExtendedLevels { get; internal set; } = new List<ExtendedLevel>(); public static List<ExtendedLevel> VanillaExtendedLevels { get { List<ExtendedLevel> list = new List<ExtendedLevel>(); foreach (ExtendedLevel extendedLevel in ExtendedLevels) { if (extendedLevel.ContentType == ContentType.Vanilla) { list.Add(extendedLevel); } } return list; } } public static List<ExtendedLevel> CustomExtendedLevels { get { List<ExtendedLevel> list = new List<ExtendedLevel>(); foreach (ExtendedLevel extendedLevel in ExtendedLevels) { if (extendedLevel.ContentType == ContentType.Custom) { list.Add(extendedLevel); } } return list; } } public static List<SelectableLevel> SeletectableLevels { get { List<SelectableLevel> list = new List<SelectableLevel>(); foreach (ExtendedLevel extendedLevel in ExtendedLevels) { list.Add(extendedLevel.SelectableLevel); } return list; } } public static List<SelectableLevel> MoonsCatalogue { get { List<SelectableLevel> list = new List<SelectableLevel>(); foreach (SelectableLevel item in OriginalContent.MoonsCatalogue) { list.Add(item); } foreach (ExtendedLevel extendedLevel in ExtendedLevels) { if (extendedLevel.ContentType == ContentType.Custom) { list.Add(extendedLevel.SelectableLevel); } } return list; } } public static List<ExtendedDungeonFlow> ExtendedDungeonFlows { get; internal set; } = new List<ExtendedDungeonFlow>(); public static List<ExtendedDungeonFlow> VanillaExtendedDungeonFlows { get { List<ExtendedDungeonFlow> list = new List<ExtendedDungeonFlow>(); foreach (ExtendedDungeonFlow extendedDungeonFlow in ExtendedDungeonFlows) { if (extendedDungeonFlow.ContentType == ContentType.Vanilla) { list.Add(extendedDungeonFlow); } } return list; } } public static List<ExtendedDungeonFlow> CustomExtendedDungeonFlows { get { List<ExtendedDungeonFlow> list = new List<ExtendedDungeonFlow>(); foreach (ExtendedDungeonFlow extendedDungeonFlow in ExtendedDungeonFlows) { if (extendedDungeonFlow.ContentType == ContentType.Custom) { list.Add(extendedDungeonFlow); } } return list; } } public static List<ExtendedWeatherEffect> ExtendedWeatherEffects { get; internal set; } = new List<ExtendedWeatherEffect>(); public static List<ExtendedWeatherEffect> VanillaExtendedWeatherEffects { get { List<ExtendedWeatherEffect> list = new List<ExtendedWeatherEffect>(); foreach (ExtendedWeatherEffect extendedWeatherEffect in ExtendedWeatherEffects) { if (extendedWeatherEffect.contentType == ContentType.Vanilla) { list.Add(extendedWeatherEffect); } } return list; } } public static List<ExtendedWeatherEffect> CustomExtendedWeatherEffects { get { List<ExtendedWeatherEffect> list = new List<ExtendedWeatherEffect>(); foreach (ExtendedWeatherEffect extendedWeatherEffect in ExtendedWeatherEffects) { if (extendedWeatherEffect.contentType == ContentType.Custom) { list.Add(extendedWeatherEffect); } } return list; } } public static List<ExtendedItem> ExtendedItems { get; internal set; } = new List<ExtendedItem>(); public static List<ExtendedItem> CustomExtendedItems { get { List<ExtendedItem> list = new List<ExtendedItem>(); foreach (ExtendedItem extendedItem in ExtendedItems) { if (extendedItem.ContentType == ContentType.Custom) { list.Add(extendedItem); } } return list; } } public static List<ExtendedEnemyType> ExtendedEnemyTypes { get; internal set; } = new List<ExtendedEnemyType>(); public static List<ExtendedEnemyType> CustomExtendedEnemyTypes { get { List<ExtendedEnemyType> list = new List<ExtendedEnemyType>(); foreach (ExtendedEnemyType extendedEnemyType in ExtendedEnemyTypes) { if (extendedEnemyType.ContentType == ContentType.Custom) { list.Add(extendedEnemyType); } } return list; } } public static List<ExtendedEnemyType> VanillaExtendedEnemyTypes { get { List<ExtendedEnemyType> list = new List<ExtendedEnemyType>(); foreach (ExtendedEnemyType extendedEnemyType in ExtendedEnemyTypes) { if (extendedEnemyType.ContentType == ContentType.Vanilla) { list.Add(extendedEnemyType); } } return list; } } public static List<AudioMixer> AudioMixers { get; internal set; } = new List<AudioMixer>(); public static List<AudioMixerGroup> AudioMixerGroups { get; internal set; } = new List<AudioMixerGroup>(); public static List<AudioMixerSnapshot> AudioMixerSnapshots { get; internal set; } = new List<AudioMixerSnapshot>(); public static List<Item> Items { get; internal set; } = new List<Item>(); public static List<EnemyType> Enemies { get; internal set; } = new List<EnemyType>(); public static void RegisterExtendedDungeonFlow(ExtendedDungeonFlow extendedDungeonFlow) { extendedDungeonFlow.ConvertObsoleteValues(); if (string.IsNullOrEmpty(((Object)extendedDungeonFlow).name)) { DebugHelper.LogWarning("Tried to register ExtendedDungeonFlow with missing name! Setting to DungeonFlow name for safety!", DebugType.Developer); ((Object)extendedDungeonFlow).name = ((Object)extendedDungeonFlow.DungeonFlow).name; } AssetBundleLoader.RegisterNewExtendedContent(extendedDungeonFlow, ((Object)extendedDungeonFlow).name); } public static void RegisterExtendedLevel(ExtendedLevel extendedLevel) { AssetBundleLoader.RegisterNewExtendedContent(extendedLevel, ((Object)extendedLevel).name); } public static void RegisterExtendedMod(ExtendedMod extendedMod) { DebugHelper.Log("Registering ExtendedMod: " + extendedMod.ModName + " Manually.", DebugType.Developer); AssetBundleLoader.RegisterExtendedMod(extendedMod); } internal static void SortExtendedMods() { ExtendedMods = new List<ExtendedMod>(ExtendedMods.OrderBy((ExtendedMod o) => o.ModName).ToList()); foreach (ExtendedMod extendedMod in ExtendedMods) { extendedMod.SortRegisteredContent(); } } } public static class OriginalContent { public static List<SelectableLevel> SelectableLevels { get; internal set; } = new List<SelectableLevel>(); public static List<SelectableLevel> MoonsCatalogue { get; internal set; } = new List<SelectableLevel>(); public static List<DungeonFlow> DungeonFlows { get; internal set; } = new List<DungeonFlow>(); public static List<Item> Items { get; internal set; } = new List<Item>(); public static List<ItemGroup> ItemGroups { get; internal set; } = new List<ItemGroup>(); public static List<EnemyType> Enemies { get; internal set; } = new List<EnemyType>(); public static List<SpawnableOutsideObject> SpawnableOutsideObjects { get; internal set; } = new List<SpawnableOutsideObject>(); public static List<GameObject> SpawnableMapObjects { get; internal set; } = new List<GameObject>(); public static List<AudioMixer> AudioMixers { get; internal set; } = new List<AudioMixer>(); public static List<AudioMixerGroup> AudioMixerGroups { get; internal set; } = new List<AudioMixerGroup>(); public static List<AudioMixerSnapshot> AudioMixerSnapshots { get; internal set; } = new List<AudioMixerSnapshot>(); public static List<LevelAmbienceLibrary> LevelAmbienceLibraries { get; internal set; } = new List<LevelAmbienceLibrary>(); public static List<ReverbPreset> ReverbPresets { get; internal set; } = new List<ReverbPreset>(); public static List<TerminalKeyword> TerminalKeywords { get; internal set; } = new List<TerminalKeyword>(); public static List<TerminalNode> TerminalNodes { get; internal set; } = new List<TerminalNode>(); } internal class EventPatches { internal static DayMode previousDayMode = (DayMode)(-1); internal static bool firedDawnEvent = false; private static EnemyVent cachedSelectedVent; internal static void InvokeExtendedEvent<T>(ExtendedEvent<T> extendedEvent, T eventParameter) { extendedEvent.Invoke(eventParameter); } internal static void OnSceneLoaded(Scene scene, LoadSceneMode loadSceneMode) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null && LevelManager.CurrentExtendedLevel.IsLevelLoaded) { previousDayMode = (DayMode)(-1); LevelManager.CurrentExtendedLevel.LevelEvents.onLevelLoaded.Invoke(); LevelManager.GlobalLevelEvents.onLevelLoaded.Invoke(); } } [HarmonyPriority(200)] [HarmonyPatch(typeof(StoryLog), "CollectLog")] [HarmonyPrefix] internal static void StoryLogCollectLog_Prefix(StoryLog __instance) { if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null && ((NetworkBehaviour)__instance).IsServer) { LevelManager.CurrentExtendedLevel.LevelEvents.onStoryLogCollected.Invoke(__instance); LevelManager.GlobalLevelEvents.onStoryLogCollected.Invoke(__instance); } } [HarmonyPriority(201)] [HarmonyPatch(typeof(DungeonGenerator), "Generate")] [HarmonyPrefix] internal static void DungeonGeneratorGenerate_Prefix() { if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null) { DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onBeforeDungeonGenerate.Invoke(Patches.RoundManager); DungeonManager.GlobalDungeonEvents.onBeforeDungeonGenerate.Invoke(Patches.RoundManager); } } [HarmonyPriority(200)] [HarmonyPatch(typeof(RoundManager), "SwitchPower")] [HarmonyPrefix] internal static void RoundManagerSwitchPower_Prefix(bool on) { if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null) { DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onPowerSwitchToggle.Invoke(on); DungeonManager.GlobalDungeonEvents.onPowerSwitchToggle.Invoke(on); } if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null) { LevelManager.CurrentExtendedLevel.LevelEvents.onPowerSwitchToggle.Invoke(on); LevelManager.GlobalLevelEvents.onPowerSwitchToggle.Invoke(on); } } [HarmonyPriority(200)] [HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")] [HarmonyPostfix] internal static void RoundManagerSpawnScrapInLevel_Postfix() { if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null) { List<GrabbableObject> param = Object.FindObjectsOfType<GrabbableObject>().ToList(); DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onSpawnedScrapObjects.Invoke(param); DungeonManager.GlobalDungeonEvents.onSpawnedScrapObjects.Invoke(param); } } [HarmonyPriority(200)] [HarmonyPatch(typeof(RoundManager), "SpawnSyncedProps")] [HarmonyPostfix] internal static void RoundManagerSpawnSyncedProps_Postfix() { if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null) { DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onSpawnedSyncedObjects.Invoke(Patches.RoundManager.spawnedSyncedObjects); DungeonManager.GlobalDungeonEvents.onSpawnedSyncedObjects.Invoke(Patches.RoundManager.spawnedSyncedObjects); } } [HarmonyPriority(200)] [HarmonyPatch(typeof(RoundManager), "SpawnEnemyFromVent")] [HarmonyPrefix] internal static void RoundManagerSpawnEventFromVent_Prefix(EnemyVent vent) { if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null) { cachedSelectedVent = vent; } } [HarmonyPriority(200)] [HarmonyPatch(typeof(RoundManager), "SpawnEnemyGameObject")] [HarmonyPostfix] internal static void RoundManagerSpawnEventFromVent_Postfix() { if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null && (Object)(object)cachedSelectedVent != (Object)null) { DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onEnemySpawnedFromVent.Invoke((cachedSelectedVent, Patches.RoundManager.SpawnedEnemies.Last())); DungeonManager.GlobalDungeonEvents.onEnemySpawnedFromVent.Invoke((cachedSelectedVent, Patches.RoundManager.SpawnedEnemies.Last())); cachedSelectedVent = null; } } [HarmonyPriority(200)] [HarmonyPatch(typeof(RoundManager), "SpawnMapObjects")] [HarmonyPostfix] internal static void RoundManagerSpawnMapObjects_Postfix() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null)) { return; } List<GameObject> list = new List<GameObject>(); Scene sceneByName = SceneManager.GetSceneByName(LevelManager.CurrentExtendedLevel.SelectableLevel.sceneName); GameObject[] rootGameObjects = ((Scene)(ref sceneByName)).GetRootGameObjects(); foreach (GameObject val in rootGameObjects) { SpawnableMapObject[] spawnableMapObjects = LevelManager.CurrentExtendedLevel.SelectableLevel.spawnableMapObjects; foreach (SpawnableMapObject val2 in spawnableMapObjects) { if (((Object)val).name.Sanitized().Contains(((Object)val2.prefabToSpawn).name.Sanitized())) { list.Add(val); } } } DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onSpawnedMapObjects.Invoke(list); DungeonManager.GlobalDungeonEvents.onSpawnedMapObjects.Invoke(list); } [HarmonyPriority(200)] [HarmonyPatch(typeof(StartOfRound), "OnShipLandedMiscEvents")] [HarmonyPrefix] internal static void StartOfRoundOnShipLandedMiscEvents_Prefix() { if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null) { LevelManager.CurrentExtendedLevel.LevelEvents.onShipLand.Invoke(); LevelManager.GlobalLevelEvents.onShipLand.Invoke(); } if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null) { DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onShipLand.Invoke(); DungeonManager.GlobalDungeonEvents.onShipLand.Invoke(); } } [HarmonyPriority(200)] [HarmonyPatch(typeof(StartOfRound), "ShipLeave")] [HarmonyPrefix] internal static void StartOfRoundShipLeave_Prefix() { if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null) { LevelManager.CurrentExtendedLevel.LevelEvents.onShipLeave.Invoke(); LevelManager.GlobalLevelEvents.onShipLeave.Invoke(); } if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null) { DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onShipLeave.Invoke(); DungeonManager.GlobalDungeonEvents.onShipLeave.Invoke(); } } [HarmonyPriority(200)] [HarmonyPatch(typeof(EntranceTeleport), "TeleportPlayerServerRpc")] [HarmonyPrefix] internal static void EntranceTeleportTeleportPlayerServerRpc_Prefix(EntranceTeleport __instance, int playerObj) { if (!((NetworkBehaviour)__instance).IsHost) { return; } if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null) { PlayerControllerB item = Patches.StartOfRound.allPlayerScripts[playerObj]; if (__instance.isEntranceToBuilding) { DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onPlayerEnterDungeon.Invoke((__instance, item)); DungeonManager.GlobalDungeonEvents.onPlayerEnterDungeon.Invoke((__instance, item)); } else { DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onPlayerExitDungeon.Invoke((__instance, item)); DungeonManager.GlobalDungeonEvents.onPlayerExitDungeon.Invoke((__instance, item)); } } if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null) { PlayerControllerB item2 = Patches.StartOfRound.allPlayerScripts[playerObj]; if (__instance.isEntranceToBuilding) { LevelManager.CurrentExtendedLevel.LevelEvents.onPlayerEnterDungeon.Invoke((__instance, item2)); LevelManager.GlobalLevelEvents.onPlayerEnterDungeon.Invoke((__instance, item2)); } else { LevelManager.CurrentExtendedLevel.LevelEvents.onPlayerExitDungeon.Invoke((__instance, item2)); LevelManager.GlobalLevelEvents.onPlayerExitDungeon.Invoke((__instance, item2)); } } } [HarmonyPriority(200)] [HarmonyPatch(typeof(LungProp), "EquipItem")] [HarmonyPrefix] internal static void LungPropEquipItem_Postfix(LungProp __instance) { if (((NetworkBehaviour)__instance).IsServer) { if ((Object)(object)DungeonManager.CurrentExtendedDungeonFlow != (Object)null) { DungeonManager.CurrentExtendedDungeonFlow.DungeonEvents.onApparatusTaken.Invoke(__instance); DungeonManager.GlobalDungeonEvents.onApparatusTaken.Invoke(__instance); } if ((Object)(object)LevelManager.CurrentExtendedLevel != (Object)null) { LevelManager.CurrentExtendedLevel.LevelEvents.onApparatusTaken.Invoke(__instance); LevelManager.GlobalLevelEvents.onApparatusTaken.Invoke(__instance); } } } [HarmonyPriority(200)] [HarmonyPatch(typeof(TimeOfDay), "GetDayPhase")] [HarmonyPostfix] internal static void TimeOfDayGetDayPhase_Postfix(DayMode __result) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if ((int)previousDayMode == -1 || previousDayMode != __result) { LevelManager.CurrentExtendedLevel.LevelEvents.onDayModeToggle.Invoke(__result); LevelManager.GlobalLevelEvents.onDayModeToggle.Invoke(__result); } previousDayMode = __result; } } public class ExtendedEvent<T> { public delegate void ParameterEvent(T param); public bool HasListeners => Listeners != 0; public int Listeners { get; internal set; } private event ParameterEvent onParameterEvent; public void Invoke(T param) { this.onParameterEvent?.Invoke(param); } public void AddListener(ParameterEvent listener) { onParameterEvent += listener; Listeners++; } public void RemoveListener(ParameterEvent listener) { onParameterEvent -= listener; Listeners--; } } public class ExtendedEvent { public delegate void Event(); public bool HasListeners => Listeners != 0; public int Listeners { get; internal set; } private event Event onEvent; public void Invoke() { this.onEvent?.Invoke(); } public void AddListener(Event listener) { onEvent += listener; Listeners++; } public void RemoveListener(Event listener) { onEvent -= listener; Listeners--; } } public static class Extensions { public static List<Tile> GetTiles(this DungeonFlow dungeonFlow) { List<Tile> list = new List<Tile>(); foreach (GraphNode node in dungeonFlow.Nodes) { foreach (TileSet tileSet in node.TileSets) { list.AddRange(GetTilesInTileSet(tileSet)); } } foreach (GraphLine line in dungeonFlow.Lines) { foreach (DungeonArchetype dungeonArchetype in line.DungeonArchetypes) { foreach (TileSet branchCapTileSet in dungeonArchetype.BranchCapTileSets) { list.AddRange(GetTilesInTileSet(branchCapTileSet)); } foreach (TileSet tileSet2 in dungeonArchetype.TileSets) { list.AddRange(GetTilesInTileSet(tileSet2)); } } } foreach (Tile item in new List<Tile>(list)) { if ((Object)(object)item == (Object)null) { list.Remove(item); } } return list; } public static List<Tile> GetTilesInTileSet(TileSet tileSet) { List<Tile> list = new List<Tile>(); if (tileSet.TileWeights != null && tileSet.TileWeights.Weights != null) { foreach (GameObjectChance weight in tileSet.TileWeights.Weights) { Tile[] componentsInChildren = weight.Value.GetComponentsInChildren<Tile>(); foreach (Tile item in componentsInChildren) { list.Add(item); } } } return list; } public static List<RandomMapObject> GetRandomMapObjects(this DungeonFlow dungeonFlow) { List<RandomMapObject> list = new List<RandomMapObject>(); foreach (Tile tile in dungeonFlow.GetTiles()) { RandomMapObject[] componentsInChildren = ((Component)tile).gameObject.GetComponentsInChildren<RandomMapObject>(); foreach (RandomMapObject item in componentsInChildren) { list.Add(item); } } return list; } public static List<SpawnSyncedObject> GetSpawnSyncedObjects(this DungeonFlow dungeonFlow) { List<SpawnSyncedObject> list = new List<SpawnSyncedObject>(); foreach (Tile tile in dungeonFlow.GetTiles()) { Doorway[] componentsInChildren = ((Component)tile).gameObject.GetComponentsInChildren<Doorway>(); foreach (Doorway val in componentsInChildren) { foreach (GameObjectWeight connectorPrefabWeight in val.ConnectorPrefabWeights) { SpawnSyncedObject[] componentsInChildren2 = connectorPrefabWeight.GameObject.GetComponentsInChildren<SpawnSyncedObject>(); foreach (SpawnSyncedObject item in componentsInChildren2) { list.Add(item); } } foreach (GameObjectWeight blockerPrefabWeight in val.BlockerPrefabWeights) { SpawnSyncedObject[] componentsInChildren3 = blockerPrefabWeight.GameObject.GetComponentsInChildren<SpawnSyncedObject>(); foreach (SpawnSyncedObject item2 in componentsInChildren3) { list.Add(item2); } } } SpawnSyncedObject[] componentsInChildren4 = ((Component)tile).gameObject.GetComponentsInChildren<SpawnSyncedObject>(); foreach (SpawnSyncedObject item3 in componentsInChildren4) { list.Add(item3); } } return list; } public static void AddReferences(this CompatibleNoun compatibleNoun, TerminalKeyword firstNoun, TerminalNode firstResult) { compatibleNoun.noun = firstNoun; compatibleNoun.result = firstResult; } public static void AddCompatibleNoun(this TerminalKeyword terminalKeyword, TerminalKeyword newNoun, TerminalNode newResult) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if (terminalKeyword.compatibleNouns == null) { terminalKeyword.compatibleNouns = (CompatibleNoun[])(object)new CompatibleNoun[0]; } CompatibleNoun val = new CompatibleNoun(); val.noun = newNoun; val.result = newResult; terminalKeyword.compatibleNouns = CollectionExtensions.AddItem<CompatibleNoun>((IEnumerable<CompatibleNoun>)terminalKeyword.compatibleNouns, val).ToArray(); } public static void AddCompatibleNoun(this TerminalNode terminalNode, TerminalKeyword newNoun, TerminalNode newResult) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if (terminalNode.terminalOptions == null) { terminalNode.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[0]; } CompatibleNoun val = new CompatibleNoun(); val.noun = newNoun; val.result = newResult; terminalNode.terminalOptions = CollectionExtensions.AddItem<CompatibleNoun>((IEnumerable<CompatibleNoun>)terminalNode.terminalOptions, val).ToArray(); } public static void Add(this IntWithRarity intWithRarity, int id, int rarity) { intWithRarity.id = id; intWithRarity.rarity = rarity; } public static string Sanitized(this string currentString) { return new string(currentString.SkipToLetters().RemoveWhitespace().ToLowerInvariant()); } public static string RemoveWhitespace(this string input) { return new string((from c in input.ToCharArray() where !char.IsWhiteSpace(c) select c).ToArray()); } public static string SkipToLetters(this string input) { return new string(input.SkipWhile((char c) => !char.IsLetter(c)).ToArray()); } public static string StripSpecialCharacters(this 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; } public static List<DungeonFlow> GetDungeonFlows(this RoundManager roundManager) { return roundManager.dungeonFlowTypes.Select((IndoorMapType i) => i.dungeonFlow).ToList(); } } internal static class Patches { private class DoorwayPairComparer : IComparer<DoorwayPair> { public int Compare(DoorwayPair x, DoorwayPair y) { int num = ((DoorwayPair)(ref y)).TileWeight.CompareTo(((DoorwayPair)(ref x)).TileWeight); if (num == 0) { return ((DoorwayPair)(ref y)).DoorwayWeight.CompareTo(((DoorwayPair)(ref x)).DoorwayWeight); } return num; } } internal const int harmonyPriority = 200; internal static string delayedSceneLoadingName = string.Empty; internal static List<string> allSceneNamesCalledToLoad = new List<string>(); public static bool hasInitiallyChangedLevel; internal static bool ranLethalLevelLoaderTerminalEvent; private static List<SpawnableMapObject> tempoarySpawnableMapObjectList = new List<SpawnableMapObject>(); internal static GameObject previousHit; internal static FootstepSurface previouslyAssignedFootstepSurface; public static StartOfRound StartOfRound { get; internal set; } public static RoundManager RoundManager { get; internal set; } public static Terminal Terminal { get; internal set; } public static TimeOfDay TimeOfDay { get; internal set; } [HarmonyPriority(200)] [HarmonyPatch(typeof(PreInitSceneScript), "Awake")] [HarmonyPrefix] internal static void PreInitSceneScriptAwake_Prefix(PreInitSceneScript __instance) { if (!Plugin.IsSetupComplete) { AudioSource val = default(AudioSource); if (((Component)__instance).TryGetComponent<AudioSource>(ref val)) { OriginalContent.AudioMixers.Add(val.outputAudioMixerGroup.audioMixer); } if (AssetBundleLoader.noBundlesFound) { AssetBundleLoader.CurrentLoadingStatus = AssetBundleLoader.LoadingStatus.Complete; AssetBundleLoader.OnBundlesFinishedLoadingInvoke(); } ContentTagParser.ImportVanillaContentTags(); } } [HarmonyPriority(200)] [HarmonyPatch(typeof(PreInitSceneScript), "ChooseLaunchOption")] [HarmonyPrefix] internal static bool PreInitSceneScriptChooseLaunchOption_Prefix() { return true; } [HarmonyPriority(200)] [HarmonyPatch(typeof(SceneManager), "LoadScene", new Type[] { typeof(string) })] [HarmonyPrefix] internal static bool SceneManagerLoadScene(string sceneName) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) if (allSceneNamesCalledToLoad.Count == 0) { List<string> list = allSceneNamesCalledToLoad; Scene activeScene = SceneManager.GetActiveScene(); list.Add(((Scene)(ref activeScene)).name); } SceneManager.GetSceneByName(sceneName); if (true) { allSceneNamesCalledToLoad.Add(sceneName); } if (sceneName == "MainMenu" && !allSceneNamesCalledToLoad.Contains("InitSceneLaunchOptions")) { DebugHelper.LogError("SceneManager has been told to load Main Menu without ever loading InitSceneLaunchOptions. This will break LethalLevelLoader. This is likely due to a \"Skip to Main Menu\" mod.", DebugType.User); return false; } if (AssetBundleLoader.CurrentLoadingStatus == AssetBundleLoader.LoadingStatus.Loading) { DebugHelper.LogWarning("SceneManager has attempted to load " + sceneName + " Scene before AssetBundles have finished loading. Pausing request until LethalLeveLoader is ready to proceed.", DebugType.User); delayedSceneLoadingName = sceneName; AssetBundleLoader.onBundlesFinishedLoading -= LoadMainMenu; AssetBundleLoader.onBundlesFinishedLoading += LoadMainMenu; return false; } return true; } internal static void LoadMainMenu() { DebugHelper.LogWarning("Proceeding with the loading of " + delayedSceneLoadingName + " Scene as LethalLevelLoader has finished loading AssetBundles.", DebugType.User); if (delayedSceneLoadingName != string.Empty) { SceneManager.LoadScene(delayedSceneLoadingName); } delayedSceneLoadingName = string.Empty; } [HarmonyPriority(200)] [HarmonyPatch(typeof(GameNetworkManager), "Start")] [HarmonyPrefix] internal static void GameNetworkManagerStart_Prefix(GameNetworkManager __instance) { if (Plugin.IsSetupComplete) { return; } LethalLevelLoaderNetworkManager.networkManager = ((Component)__instance).GetComponent<NetworkManager>(); foreach (NetworkPrefab prefab in ((Component)__instance).GetComponent<NetworkManager>().NetworkConfig.Prefabs.m_Prefabs) { if (((Object)prefab.Prefab).name.Contains("EntranceTeleport") && (Object)(object)prefab.Prefab.GetComponent<AudioSource>() != (Object)null) { OriginalContent.AudioMixers.Add(prefab.Prefab.GetComponent<AudioSource>().outputAudioMixerGroup.audioMixer); } } GameObject val = PrefabHelper.CreateNetworkPrefab("LethalLevelLoaderNetworkManagerTest"); val.AddComponent<LethalLevelLoaderNetworkManager>(); val.GetComponent<NetworkObject>().DontDestroyWithOwner = true; val.GetComponent<NetworkObject>().SceneMigrationSynchronization = true; val.GetComponent<NetworkObject>().DestroyWithScene = false; Object.DontDestroyOnLoad((Object)(object)val); LethalLevelLoaderNetworkManager.networkingManagerPrefab = val; LethalLevelLoaderNetworkManager.RegisterNetworkPrefab(val); AssetBundleLoader.NetworkRegisterCustomContent(((Component)__instance).GetComponent<NetworkManager>()); LethalLevelLoaderNetworkManager.RegisterPrefabs(((Component)__instance).GetComponent<NetworkManager>()); } [HarmonyPriority(200)] [HarmonyPatch(typeof(GameNetworkManager), "SaveGameValues")] [HarmonyPostfix] internal static void GameNetworkManagerSaveGameValues_Postfix(GameNetworkManager __instance) { if (__instance.isHostingGame && StartOfRound.Instance.inShipPhase && !StartOfRound.Instance.isChallengeFile) { SaveManager.SaveGameValues(); } } [HarmonyPriority(200)] [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPrefix] internal static void StartOfRoundAwake_Prefix(StartOfRound __instance) { Plugin.OnBeforeSetupInvoke(); StartOfRound = __instance; RoundManager = Object.FindFirstObjectByType<RoundManager>(); Terminal = Object.FindFirstObjectByType<Terminal>(); TimeOfDay = Object.FindFirstObjectByType<TimeOfDay>(); SceneManager.sceneLoaded += OnSceneLoaded; SceneManager.sceneLoaded += EventPatches.OnSceneLoaded; if (!Plugin.IsSetupComplete) { StartOfRound.allItemsList.itemsList.RemoveAt(2); DebugStopwatch.StartStopWatch("Scrape Vanilla Content"); ContentExtractor.TryScrapeVanillaItems(StartOfRound); ContentExtractor.TryScrapeVanillaContent(StartOfRound, RoundManager); ContentExtractor.ObtainSpecialItemReferences(); } if (((Component)GameNetworkManager.Instance).GetComponent<NetworkManager>().IsServer) { Object.Instantiate<GameObject>(LethalLevelLoaderNetworkManager.networkingManagerPrefab).GetComponent<NetworkObject>().Spawn(false); } RoundManager.firstTimeDungeonAudios = CollectionExtensions.AddItem<AudioClip>((IEnumerable<AudioClip>)RoundManager.firstTimeDungeonAudios.ToList(), RoundManager.firstTimeDungeonAudios[0]).ToArray(); DebugStopwatch.StartStopWatch("Fix AudioSource Settings"); AudioSource[] array = Resources.FindObjectsOfTypeAll<AudioSource>(); foreach (AudioSource val in array) { val.spatialize = false; } if (!Plugin.IsSetupComplete) { TerminalManager.CacheTerminalReferences(); LevelManager.InitalizeShipAnimatorOverrideController(); DungeonLoader.defaultKeyPrefab = RoundManager.keyPrefab; LevelLoader.defaultQuicksandPrefab = RoundManager.quicksandPrefab; DebugStopwatch.StartStopWatch("Create Vanilla ExtendedContent"); AssetBundleLoader.CreateVanillaExtendedDungeonFlows(); AssetBundleLoader.Cre