Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Mausoleum Fix v1.1.0
MausoleumCompatPatch.dll
Decompiled 2 months agousing 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 BepInEx; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using REPOLib; using REPOLib.Modules; using UnityEngine; using UnityEngine.AI; using UnityEngine.Audio; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Empress")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.11.0")] [assembly: AssemblyInformationalVersion("1.0.11")] [assembly: AssemblyProduct("MausoleumCompatPatch")] [assembly: AssemblyTitle("MausoleumCompatPatch")] [assembly: AssemblyVersion("1.0.11.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace MausoleumCompatPatch { [BepInPlugin("empress.repo.mausoleumcompatpatch", "Empress Mausoleum Compat Patch", "1.0.13")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class MausoleumCompatPatchPlugin : BaseUnityPlugin { private sealed class MausoleumPrefabBuckets { public List<GameObject> StartRooms { get; set; } = new List<GameObject>(); public List<GameObject> Normal1 { get; set; } = new List<GameObject>(); public List<GameObject> Passage1 { get; set; } = new List<GameObject>(); public List<GameObject> DeadEnd1 { get; set; } = new List<GameObject>(); public List<GameObject> Extraction1 { get; set; } = new List<GameObject>(); public List<GameObject> Normal2 { get; set; } = new List<GameObject>(); public List<GameObject> Passage2 { get; set; } = new List<GameObject>(); public List<GameObject> DeadEnd2 { get; set; } = new List<GameObject>(); public List<GameObject> Extraction2 { get; set; } = new List<GameObject>(); public List<GameObject> Normal3 { get; set; } = new List<GameObject>(); public List<GameObject> Passage3 { get; set; } = new List<GameObject>(); public List<GameObject> DeadEnd3 { get; set; } = new List<GameObject>(); public List<GameObject> Extraction3 { get; set; } = new List<GameObject>(); public int TotalModuleCount => Normal1.Count + Passage1.Count + DeadEnd1.Count + Extraction1.Count + Normal2.Count + Passage2.Count + DeadEnd2.Count + Extraction2.Count + Normal3.Count + Passage3.Count + DeadEnd3.Count + Extraction3.Count; } internal const string PluginGuid = "empress.repo.mausoleumcompatpatch"; internal const string PluginName = "Empress Mausoleum Compat Patch"; internal const string PluginVersion = "1.0.13"; private const string MausoleumBundleFileName = "melanierepointeriors.repobundle"; private const string MausoleumLevelName = "Mel Mausoleum"; private const string MausoleumLevelResourcePath = "Mausoleum"; private const float MausoleumLevelPointCheckRadius = 0.5f; private const float MausoleumLevelPointRepairRadius = 2f; private const float MausoleumLevelPointConnectDistance = 15f; private const float MausoleumLevelPointConnectForwardDot = -0.8f; private const float MausoleumLevelPointConnectApproachDot = 0.8f; private const float MausoleumLevelPointValidationDelay = 0.5f; private static readonly string[] MausoleumStartRoomNames = new string[1] { "MausoleumStart0" }; private static readonly string[] MausoleumNormal1Names = new string[3] { "MausoleumNorm0", "MausoleumNorm1", "MausoleumNorm2" }; private static readonly string[] MausoleumPassage1Names = new string[2] { "MausoleumPass0", "MausoleumPass1" }; private static readonly string[] MausoleumDeadEnd1Names = new string[2] { "MausoleumEnd0", "MausoleumEnd1" }; private static readonly string[] MausoleumExtraction1Names = new string[1] { "MausoleumExt0" }; private static readonly string[] MausoleumNormal2Names = new string[2] { "MausoleumNorm3", "MausoleumNorm5" }; private static readonly string[] MausoleumPassage2Names = new string[1] { "MausoleumPass2" }; private static readonly string[] MausoleumDeadEnd2Names = Array.Empty<string>(); private static readonly string[] MausoleumExtraction2Names = Array.Empty<string>(); private static readonly string[] MausoleumNormal3Names = new string[2] { "MausoleumNorm4", "MausoleumNorm6" }; private static readonly string[] MausoleumPassage3Names = Array.Empty<string>(); private static readonly string[] MausoleumDeadEnd3Names = Array.Empty<string>(); private static readonly string[] MausoleumExtraction3Names = Array.Empty<string>(); private readonly Harmony _mausoleumHarmony = new Harmony("empress.repo.mausoleumcompatpatch"); private AssetBundle? _mausoleumBundle; private bool _mausoleumRepairApplied; private bool _mausoleumRepairQueued; private bool _mausoleumLoggedMissingBundle; private bool _mausoleumLoggedMissingPrefabs; private bool _mausoleumLoggedDoorMapFallback; private bool _mausoleumLoggedRepairAttempt; internal static MausoleumCompatPatchPlugin? Instance { get; private set; } private void Awake() { Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); BundleLoader.OnAllBundlesLoaded += MausoleumHandleBundlesLoaded; SceneManager.activeSceneChanged += MausoleumOnActiveSceneChanged; _mausoleumHarmony.PatchAll(); if ((Object)(object)RunManager.instance != (Object)null) { ((MonoBehaviour)this).StartCoroutine(MausoleumRepairWhenReady()); } } private void OnDestroy() { BundleLoader.OnAllBundlesLoaded -= MausoleumHandleBundlesLoaded; SceneManager.activeSceneChanged -= MausoleumOnActiveSceneChanged; _mausoleumHarmony.UnpatchSelf(); if (Instance == this) { Instance = null; } } private void MausoleumOnActiveSceneChanged(Scene current, Scene next) { _mausoleumRepairApplied = false; _mausoleumRepairQueued = false; _mausoleumLoggedRepairAttempt = false; if ((Object)(object)RunManager.instance != (Object)null) { ((MonoBehaviour)this).StartCoroutine(MausoleumRepairWhenReady()); } } private void MausoleumHandleBundlesLoaded() { if (!_mausoleumRepairQueued && !_mausoleumRepairApplied) { _mausoleumRepairQueued = true; ((MonoBehaviour)this).StartCoroutine(MausoleumRepairWhenReady()); } } private IEnumerator MausoleumRepairWhenReady() { yield return null; for (int attempt = 0; attempt < 120; attempt++) { if (_mausoleumRepairApplied) { break; } if (MausoleumTryRepairLevel()) { break; } yield return null; } _mausoleumRepairQueued = false; } internal bool MausoleumTryRepairCurrentLevel() { List<Level> list = new List<Level>(); if ((Object)(object)LevelGenerator.Instance != (Object)null && (Object)(object)LevelGenerator.Instance.Level != (Object)null) { list.Add(LevelGenerator.Instance.Level); } if ((Object)(object)RunManager.instance != (Object)null && (Object)(object)RunManager.instance.levelCurrent != (Object)null) { list.Add(RunManager.instance.levelCurrent); } return MausoleumTryRepairLevel((IEnumerable<Level>?)list); } internal bool MausoleumTryRepairLevel(Level? level) { if (!MausoleumIsMausoleumLevel(level)) { return false; } if (MausoleumHasValidLevelData(level)) { _mausoleumRepairApplied = true; return true; } return MausoleumTryRepairSpecificLevel(level); } private bool MausoleumTryRepairLevel(IEnumerable<Level>? candidates = null) { Level val = MausoleumFindLevel(candidates) ?? MausoleumFindLevel(Levels.AllLevels); if ((Object)(object)val == (Object)null) { return false; } if (MausoleumHasValidLevelData(val)) { _mausoleumRepairApplied = true; return true; } AssetBundle val2 = MausoleumGetBundle(); if ((Object)(object)val2 == (Object)null) { if (!_mausoleumLoggedMissingBundle) { _mausoleumLoggedMissingBundle = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)"Empress Mausoleum Compat Patch could not locate the Mausoleum bundle."); } return false; } _mausoleumLoggedMissingBundle = false; MausoleumPrefabBuckets mausoleumPrefabBuckets = MausoleumCollectPrefabs(val2); if (mausoleumPrefabBuckets.StartRooms.Count == 0 || mausoleumPrefabBuckets.TotalModuleCount == 0) { if (!_mausoleumLoggedMissingPrefabs) { _mausoleumLoggedMissingPrefabs = true; ((BaseUnityPlugin)this).Logger.LogError((object)"Empress Mausoleum Compat Patch could not rebuild the Mausoleum prefab lists from the original bundle."); } return false; } _mausoleumLoggedMissingPrefabs = false; MausoleumApplyHideFlags((Object)(object)val2); MausoleumApplyHideFlags((Object)(object)val); MausoleumEnsureLevelFallbackData(val); MausoleumRegisterLevelObjects(val); MausoleumApplyPrefabBuckets(val, mausoleumPrefabBuckets); _mausoleumRepairApplied = (val.StartRooms?.Count ?? 0) > 0 && MausoleumCountModules(val) > 0; if (_mausoleumRepairApplied) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Empress Mausoleum Compat Patch repaired {((Object)val).name} with {val.StartRooms?.Count ?? 0} start rooms and {MausoleumCountModules(val)} modules."); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"Empress Mausoleum Compat Patch found Mausoleum assets but only rebuilt {val.StartRooms?.Count ?? 0} start rooms and {MausoleumCountModules(val)} modules."); } return _mausoleumRepairApplied; } private bool MausoleumTryRepairSpecificLevel(Level level) { if (!MausoleumIsMausoleumLevel(level)) { return false; } if (MausoleumHasValidLevelData(level)) { _mausoleumRepairApplied = true; return true; } if (!_mausoleumLoggedRepairAttempt) { _mausoleumLoggedRepairAttempt = true; ((BaseUnityPlugin)this).Logger.LogInfo((object)("Empress Mausoleum Compat Patch is rebuilding " + ((Object)level).name + " from the original bundle.")); } AssetBundle val = MausoleumGetBundle(); if ((Object)(object)val == (Object)null) { if (!_mausoleumLoggedMissingBundle) { _mausoleumLoggedMissingBundle = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)"Empress Mausoleum Compat Patch could not locate the Mausoleum bundle."); } return false; } _mausoleumLoggedMissingBundle = false; MausoleumPrefabBuckets mausoleumPrefabBuckets = MausoleumCollectPrefabs(val); if (mausoleumPrefabBuckets.StartRooms.Count == 0 || mausoleumPrefabBuckets.TotalModuleCount == 0) { if (!_mausoleumLoggedMissingPrefabs) { _mausoleumLoggedMissingPrefabs = true; ((BaseUnityPlugin)this).Logger.LogError((object)"Empress Mausoleum Compat Patch could not rebuild the Mausoleum prefab lists from the original bundle."); } return false; } _mausoleumLoggedMissingPrefabs = false; MausoleumApplyHideFlags((Object)(object)val); MausoleumApplyHideFlags((Object)(object)level); MausoleumEnsureLevelFallbackData(level); MausoleumRegisterLevelObjects(level); MausoleumApplyPrefabBuckets(level, mausoleumPrefabBuckets); _mausoleumRepairApplied = (level.StartRooms?.Count ?? 0) > 0 && MausoleumCountModules(level) > 0; if (_mausoleumRepairApplied) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Empress Mausoleum Compat Patch repaired {((Object)level).name} with {level.StartRooms?.Count ?? 0} start rooms and {MausoleumCountModules(level)} modules."); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"Empress Mausoleum Compat Patch found Mausoleum assets but only rebuilt {level.StartRooms?.Count ?? 0} start rooms and {MausoleumCountModules(level)} modules."); } return _mausoleumRepairApplied; } private static Level? MausoleumFindLevel(IEnumerable<Level>? candidates) { if (candidates == null) { return null; } foreach (Level candidate in candidates) { if (MausoleumIsMausoleumLevel(candidate)) { return candidate; } } return null; } private AssetBundle? MausoleumGetBundle() { if ((Object)(object)_mausoleumBundle != (Object)null) { return _mausoleumBundle; } foreach (AssetBundle allLoadedAssetBundle in AssetBundle.GetAllLoadedAssetBundles()) { try { if (MausoleumBundleMatches(allLoadedAssetBundle)) { _mausoleumBundle = allLoadedAssetBundle; return _mausoleumBundle; } } catch { } } string text = Directory.GetFiles(Paths.PluginPath, "melanierepointeriors.repobundle", SearchOption.AllDirectories).FirstOrDefault(); if (string.IsNullOrWhiteSpace(text)) { return null; } _mausoleumBundle = AssetBundle.LoadFromFile(text); return _mausoleumBundle; } private static MausoleumPrefabBuckets MausoleumCollectPrefabs(AssetBundle bundle) { Dictionary<string, GameObject> prefabsByName = new Dictionary<string, GameObject>(StringComparer.OrdinalIgnoreCase); StartRoom[] array = bundle.LoadAllAssets<StartRoom>(); foreach (StartRoom val in array) { MausoleumAddAssetByName(prefabsByName, ((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null); } Module[] array2 = bundle.LoadAllAssets<Module>(); foreach (Module val2 in array2) { MausoleumAddAssetByName(prefabsByName, ((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject : null); } GameObject[] array3 = bundle.LoadAllAssets<GameObject>(); foreach (GameObject prefab in array3) { MausoleumAddAssetByName(prefabsByName, prefab); } MausoleumPopulatePrefabLookupFromResources(prefabsByName); return new MausoleumPrefabBuckets { StartRooms = MausoleumResolvePrefabs(prefabsByName, MausoleumStartRoomNames), Normal1 = MausoleumResolvePrefabs(prefabsByName, MausoleumNormal1Names), Passage1 = MausoleumResolvePrefabs(prefabsByName, MausoleumPassage1Names), DeadEnd1 = MausoleumResolvePrefabs(prefabsByName, MausoleumDeadEnd1Names), Extraction1 = MausoleumResolvePrefabs(prefabsByName, MausoleumExtraction1Names), Normal2 = MausoleumResolvePrefabs(prefabsByName, MausoleumNormal2Names), Passage2 = MausoleumResolvePrefabs(prefabsByName, MausoleumPassage2Names), DeadEnd2 = MausoleumResolvePrefabs(prefabsByName, MausoleumDeadEnd2Names), Extraction2 = MausoleumResolvePrefabs(prefabsByName, MausoleumExtraction2Names), Normal3 = MausoleumResolvePrefabs(prefabsByName, MausoleumNormal3Names), Passage3 = MausoleumResolvePrefabs(prefabsByName, MausoleumPassage3Names), DeadEnd3 = MausoleumResolvePrefabs(prefabsByName, MausoleumDeadEnd3Names), Extraction3 = MausoleumResolvePrefabs(prefabsByName, MausoleumExtraction3Names) }; } private static void MausoleumApplyPrefabBuckets(Level level, MausoleumPrefabBuckets prefabs) { level.StartRooms = MausoleumRegisterPrefabs(level, "StartRoom", prefabs.StartRooms); level.ModulesNormal1 = MausoleumRegisterPrefabs(level, "Normal", prefabs.Normal1); level.ModulesPassage1 = MausoleumRegisterPrefabs(level, "Passage", prefabs.Passage1); level.ModulesDeadEnd1 = MausoleumRegisterPrefabs(level, "DeadEnd", prefabs.DeadEnd1); level.ModulesExtraction1 = MausoleumRegisterPrefabs(level, "Extraction", prefabs.Extraction1); level.ModulesNormal2 = MausoleumRegisterPrefabs(level, "Normal", prefabs.Normal2); level.ModulesPassage2 = MausoleumRegisterPrefabs(level, "Passage", prefabs.Passage2); level.ModulesDeadEnd2 = MausoleumRegisterPrefabs(level, "DeadEnd", prefabs.DeadEnd2); level.ModulesExtraction2 = MausoleumRegisterPrefabs(level, "Extraction", prefabs.Extraction2); level.ModulesNormal3 = MausoleumRegisterPrefabs(level, "Normal", prefabs.Normal3); level.ModulesPassage3 = MausoleumRegisterPrefabs(level, "Passage", prefabs.Passage3); level.ModulesDeadEnd3 = MausoleumRegisterPrefabs(level, "DeadEnd", prefabs.DeadEnd3); level.ModulesExtraction3 = MausoleumRegisterPrefabs(level, "Extraction", prefabs.Extraction3); } private static void MausoleumPopulatePrefabLookupFromResources(IDictionary<string, GameObject> prefabsByName) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) StartRoom[] array = Resources.FindObjectsOfTypeAll<StartRoom>(); Scene scene; foreach (StartRoom val in array) { if (!((Object)(object)val == (Object)null)) { scene = ((Component)val).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { MausoleumAddAssetByName(prefabsByName, ((Component)val).gameObject); } } } Module[] array2 = Resources.FindObjectsOfTypeAll<Module>(); foreach (Module val2 in array2) { if (!((Object)(object)val2 == (Object)null)) { scene = ((Component)val2).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { MausoleumAddAssetByName(prefabsByName, ((Component)val2).gameObject); } } } GameObject[] array3 = Resources.FindObjectsOfTypeAll<GameObject>(); foreach (GameObject val3 in array3) { if (!((Object)(object)val3 == (Object)null)) { scene = val3.scene; if (!((Scene)(ref scene)).IsValid()) { MausoleumAddAssetByName(prefabsByName, val3); } } } } private static void MausoleumAddAssetByName(IDictionary<string, GameObject> prefabsByName, GameObject? prefab) { if (!((Object)(object)prefab == (Object)null) && !string.IsNullOrWhiteSpace(((Object)prefab).name) && !prefabsByName.ContainsKey(((Object)prefab).name)) { prefabsByName[((Object)prefab).name] = prefab; } } private static List<GameObject> MausoleumResolvePrefabs(IReadOnlyDictionary<string, GameObject> prefabsByName, IEnumerable<string> names) { List<GameObject> list = new List<GameObject>(); foreach (string name in names) { if (prefabsByName.TryGetValue(name, out GameObject value)) { list.Add(value); } } return list; } private static void MausoleumRegisterLevelObjects(Level level) { if ((Object)(object)level.ConnectObject != (Object)null) { MausoleumRegisterNetworkPrefab("Level/" + (level.ResourcePath ?? "Mausoleum") + "/Other/" + ((Object)level.ConnectObject).name, level.ConnectObject); } if ((Object)(object)level.BlockObject != (Object)null) { MausoleumRegisterNetworkPrefab("Level/" + (level.ResourcePath ?? "Mausoleum") + "/Other/" + ((Object)level.BlockObject).name, level.BlockObject); } } private static bool MausoleumBundleMatches(AssetBundle bundle) { if ((Object)(object)bundle == (Object)null) { return false; } try { Level[] array = bundle.LoadAllAssets<Level>(); foreach (Level val in array) { if (!((Object)(object)val == (Object)null) && MausoleumIsMausoleumLevel(val)) { return true; } } } catch { } try { if (bundle.GetAllAssetNames().Any((string assetName) => assetName.Contains("mausoleum", StringComparison.OrdinalIgnoreCase))) { return true; } } catch { } try { GameObject[] array2 = bundle.LoadAllAssets<GameObject>(); foreach (GameObject val2 in array2) { if (!((Object)(object)val2 == (Object)null) && !string.IsNullOrWhiteSpace(((Object)val2).name) && (((Object)val2).name.StartsWith("MausoleumStart", StringComparison.OrdinalIgnoreCase) || ((Object)val2).name.StartsWith("MausoleumNorm", StringComparison.OrdinalIgnoreCase) || ((Object)val2).name.StartsWith("MausoleumPass", StringComparison.OrdinalIgnoreCase) || ((Object)val2).name.StartsWith("MausoleumEnd", StringComparison.OrdinalIgnoreCase) || ((Object)val2).name.StartsWith("MausoleumExt", StringComparison.OrdinalIgnoreCase) || string.Equals(((Object)val2).name, "MausoleumDoor", StringComparison.OrdinalIgnoreCase) || string.Equals(((Object)val2).name, "MausoleumBlock", StringComparison.OrdinalIgnoreCase))) { return true; } } } catch { } return false; } private static List<PrefabRef> MausoleumRegisterPrefabs(Level level, string moduleTypeName, IEnumerable<GameObject> prefabs) { List<PrefabRef> list = new List<PrefabRef>(); foreach (GameObject item in prefabs.OrderBy<GameObject, string>((GameObject gameObject) => ((Object)gameObject).name, StringComparer.OrdinalIgnoreCase)) { PrefabRef val = MausoleumRegisterNetworkPrefab("Level/" + ((Object)level).name + "/" + moduleTypeName + "/" + ((Object)item).name, item); if (val != null) { list.Add(val); } } return list; } private static PrefabRef? MausoleumRegisterNetworkPrefab(string prefabId, GameObject prefab) { PrefabRef val = MausoleumGetRegisteredPrefabRef(prefabId); if (val != null) { return val; } MausoleumPreparePrefab(prefab); Utilities.FixAudioMixerGroups(prefab); return NetworkPrefabs.RegisterNetworkPrefab(prefabId, prefab); } private static PrefabRef? MausoleumGetRegisteredPrefabRef(string prefabId) { if (!NetworkPrefabs.PrefabRefs.TryGetValue(prefabId, out var value) || value == null) { return null; } if (string.IsNullOrWhiteSpace(value.ResourcePath) || string.Equals(value.ResourcePath, prefabId, StringComparison.OrdinalIgnoreCase)) { return value; } return null; } private static void MausoleumPreparePrefab(GameObject prefab) { MausoleumApplyHideFlags((Object)(object)prefab); MausoleumAssignFallbackAudioMixerGroups(prefab); MausoleumAssignFallbackPhysAttributes(prefab); MausoleumAssignFallbackHingeData(prefab); } private static void MausoleumAssignFallbackAudioMixerGroups(GameObject prefab) { AudioMixerGroup val = MausoleumGetFallbackAudioMixerGroup(); if ((Object)(object)prefab == (Object)null || (Object)(object)val == (Object)null) { return; } AudioSource[] componentsInChildren = prefab.GetComponentsInChildren<AudioSource>(true); foreach (AudioSource val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !((Object)(object)val2.outputAudioMixerGroup != (Object)null)) { val2.outputAudioMixerGroup = val; } } } private static void MausoleumAssignFallbackPhysAttributes(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return; } NotValuableObject[] componentsInChildren = prefab.GetComponentsInChildren<NotValuableObject>(true); foreach (NotValuableObject val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.physAttributePreset != (Object)null)) { Rigidbody component = ((Component)val).GetComponent<Rigidbody>(); float mass = (((Object)(object)component != (Object)null && component.mass > 0f) ? component.mass : 1f); val.physAttributePreset = MausoleumCreateFallbackPhysAttribute(mass); } } } private static void MausoleumAssignFallbackHingeData(GameObject prefab) { if (!((Object)(object)prefab == (Object)null)) { PhysGrabHinge[] componentsInChildren = prefab.GetComponentsInChildren<PhysGrabHinge>(true); for (int i = 0; i < componentsInChildren.Length; i++) { MausoleumEnsurePhysGrabHingeCompatibility(componentsInChildren[i]); } } } internal static void MausoleumEnsurePhysGrabHingeCompatibility(PhysGrabHinge? hinge) { //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)hinge == (Object)null)) { PhysGrabHinge val = hinge; if (val.moveLoop == null) { val.moveLoop = MausoleumCreateFallbackSound(); } if ((Object)(object)hinge.hingeAudio == (Object)null) { hinge.hingeAudio = MausoleumCreateFallbackHingeAudio(); } else { MausoleumNormalizeSound(hinge.hingeAudio.moveLoop); MausoleumNormalizeSound(hinge.hingeAudio.moveLoopEnd); MausoleumNormalizeSound(hinge.hingeAudio.Close); MausoleumNormalizeSound(hinge.hingeAudio.CloseHeavy); MausoleumNormalizeSound(hinge.hingeAudio.Open); MausoleumNormalizeSound(hinge.hingeAudio.OpenHeavy); MausoleumNormalizeSound(hinge.hingeAudio.HingeBreak); } val = hinge; if (val.audioSource == null) { val.audioSource = ((Component)hinge).GetComponent<AudioSource>() ?? ((Component)hinge).gameObject.AddComponent<AudioSource>(); } hinge.audioSource.playOnAwake = false; if ((Object)(object)hinge.audioSource.outputAudioMixerGroup == (Object)null) { hinge.audioSource.outputAudioMixerGroup = MausoleumGetFallbackAudioMixerGroup(); } if (MausoleumShouldReplaceHingePoint(hinge)) { hinge.hingePoint = MausoleumFindOrCreateBestHingePoint(hinge); } HingeJoint val2 = ((Component)hinge).GetComponent<HingeJoint>(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)hinge).gameObject.AddComponent<HingeJoint>(); } ((Joint)val2).autoConfigureConnectedAnchor = true; ((Joint)val2).axis = Vector3.right; if ((Object)(object)((Component)hinge).GetComponent<PhysGrabObjectImpactDetector>() == (Object)null) { ((Component)hinge).gameObject.AddComponent<PhysGrabObjectImpactDetector>(); } if (MausoleumShouldReplaceHingePoint(hinge)) { hinge.hingePoint = MausoleumFindOrCreateBestHingePoint(hinge); } if ((Object)(object)hinge.hingePoint != (Object)null && (Object)(object)val2 != (Object)null) { ((Joint)val2).anchor = hinge.hingePoint.localPosition; } val = hinge; if (val.wallTagHinges == null) { val.wallTagHinges = Array.Empty<PhysGrabHinge>(); } val = hinge; if (val.wallTagObjects == null) { val.wallTagObjects = Array.Empty<GameObject>(); } val = hinge; if (val.lowPassTriggers == null) { val.lowPassTriggers = Array.Empty<LowPassTrigger>(); } } } private static bool MausoleumShouldReplaceHingePoint(PhysGrabHinge hinge) { if ((Object)(object)hinge == (Object)null) { return false; } if ((Object)(object)hinge.hingePoint == (Object)null) { return true; } if (!MausoleumIsCoffinLidHinge(hinge)) { return false; } if (!((Object)(object)hinge.hingePoint == (Object)(object)((Component)hinge).transform) && !string.Equals(((Object)hinge.hingePoint).name, "Mesh", StringComparison.OrdinalIgnoreCase) && !string.Equals(((Object)hinge.hingePoint).name, "Collision", StringComparison.OrdinalIgnoreCase)) { return string.Equals(((Object)hinge.hingePoint).name, "Mausoleum Patch Hinge Point", StringComparison.OrdinalIgnoreCase); } return true; } private static bool MausoleumIsCoffinLidHinge(PhysGrabHinge hinge) { if ((Object)(object)hinge == (Object)null) { return false; } if (!string.Equals(((Object)((Component)hinge).transform).name, "Hinge Template", StringComparison.OrdinalIgnoreCase)) { return false; } Transform parent = ((Component)hinge).transform.parent; if ((Object)(object)parent == (Object)null) { return false; } if (((Object)parent).name.IndexOf("Coffin", StringComparison.OrdinalIgnoreCase) < 0) { return ((Object)parent).name.IndexOf("Lid", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } private static Transform MausoleumFindOrCreateBestHingePoint(PhysGrabHinge hinge) { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) PhysGrabHinge hinge2 = hinge; if ((Object)(object)hinge2 == (Object)null) { throw new ArgumentNullException("hinge"); } Transform val = MausoleumFindDirectChildByExactName(((Component)hinge2).transform, "Hinge"); if ((Object)(object)val != (Object)null) { return val; } Transform val2 = MausoleumFindDirectChildContaining(((Component)hinge2).transform, "Hinge", "Audio"); if ((Object)(object)val2 != (Object)null) { return val2; } if (MausoleumIsCoffinLidHinge(hinge2)) { Transform val3 = MausoleumFindDirectChildByExactName(((Component)hinge2).transform, "Collision"); if ((Object)(object)val3 != (Object)null) { Vector3 localPosition = default(Vector3); ((Vector3)(ref localPosition))..ctor(val3.localPosition.x + val3.localScale.x * 0.5f, val3.localPosition.y + val3.localScale.y, val3.localPosition.z - 0.05f); return MausoleumCreateHingePoint(((Component)hinge2).transform, "Hinge", localPosition); } } Rigidbody val4 = ((IEnumerable<Rigidbody>)((Component)hinge2).GetComponentsInChildren<Rigidbody>(true)).FirstOrDefault((Func<Rigidbody, bool>)((Rigidbody rigidbody) => (Object)(object)rigidbody != (Object)null && (Object)(object)((Component)rigidbody).transform != (Object)(object)((Component)hinge2).transform)); if ((Object)(object)val4 != (Object)null) { return ((Component)val4).transform; } if (((Component)hinge2).transform.childCount > 0) { return ((Component)hinge2).transform.GetChild(0); } return MausoleumCreateHingePoint(((Component)hinge2).transform, "Mausoleum Patch Hinge Point", Vector3.zero); } private static Transform? MausoleumFindDirectChildByExactName(Transform parent, string name) { for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if ((Object)(object)child != (Object)null && string.Equals(((Object)child).name, name, StringComparison.OrdinalIgnoreCase)) { return child; } } return null; } private static Transform? MausoleumFindDirectChildContaining(Transform parent, string value, string? excludeValue = null) { for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if (!((Object)(object)child == (Object)null) && ((Object)child).name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0 && (string.IsNullOrWhiteSpace(excludeValue) || ((Object)child).name.IndexOf(excludeValue, StringComparison.OrdinalIgnoreCase) < 0)) { return child; } } return null; } private static Transform MausoleumCreateHingePoint(Transform parent, string name, Vector3 localPosition) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) Transform val = MausoleumFindDirectChildByExactName(parent, name); if ((Object)(object)val != (Object)null) { val.localPosition = localPosition; val.localRotation = Quaternion.identity; val.localScale = Vector3.one; return val; } GameObject val2 = new GameObject(name); val2.transform.SetParent(parent, false); val2.transform.localPosition = localPosition; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = Vector3.one; MausoleumApplyHideFlags((Object)val2); return val2.transform; } private static HingeAudio MausoleumCreateFallbackHingeAudio() { HingeAudio obj = ScriptableObject.CreateInstance<HingeAudio>(); obj.moveLoopEnabled = false; obj.moveLoop = MausoleumCreateFallbackSound(); obj.moveLoopEnd = MausoleumCreateFallbackSound(); obj.Close = MausoleumCreateFallbackSound(); obj.CloseHeavy = MausoleumCreateFallbackSound(); obj.Open = MausoleumCreateFallbackSound(); obj.OpenHeavy = MausoleumCreateFallbackSound(); obj.HingeBreak = MausoleumCreateFallbackSound(); MausoleumApplyHideFlags((Object)(object)obj); return obj; } private static Sound MausoleumCreateFallbackSound() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_000c: Expected O, but got Unknown Sound val = new Sound(); MausoleumNormalizeSound(val); return val; } private static void MausoleumNormalizeSound(Sound? sound) { if (sound != null) { Sound val = sound; if (val.Sounds == null) { val.Sounds = Array.Empty<AudioClip>(); } val = sound; if (val.LowPassIgnoreColliders == null) { val.LowPassIgnoreColliders = new List<Collider>(); } } } private static PhysAttribute MausoleumCreateFallbackPhysAttribute(float mass) { PhysAttribute obj = ScriptableObject.CreateInstance<PhysAttribute>(); obj.mass = Mathf.Max(0.01f, mass); MausoleumApplyHideFlags((Object)(object)obj); return obj; } private static AudioMixerGroup? MausoleumGetFallbackAudioMixerGroup() { if ((Object)(object)AudioManager.instance == (Object)null) { return null; } return AudioManager.instance.SoundMasterGroup ?? AudioManager.instance.PersistentSoundGroup ?? AudioManager.instance.MusicMasterGroup ?? AudioManager.instance.MicrophoneSoundGroup ?? AudioManager.instance.MicrophoneSpectateGroup ?? AudioManager.instance.TTSSoundGroup ?? AudioManager.instance.TTSSpectateGroup; } private static int MausoleumCountModules(Level level) { return (level.ModulesNormal1?.Count ?? 0) + (level.ModulesPassage1?.Count ?? 0) + (level.ModulesDeadEnd1?.Count ?? 0) + (level.ModulesExtraction1?.Count ?? 0) + (level.ModulesNormal2?.Count ?? 0) + (level.ModulesPassage2?.Count ?? 0) + (level.ModulesDeadEnd2?.Count ?? 0) + (level.ModulesExtraction2?.Count ?? 0) + (level.ModulesNormal3?.Count ?? 0) + (level.ModulesPassage3?.Count ?? 0) + (level.ModulesDeadEnd3?.Count ?? 0) + (level.ModulesExtraction3?.Count ?? 0); } private static bool MausoleumHasValidLevelData(Level? level) { if ((Object)(object)level == (Object)null) { return false; } if (MausoleumCountValidPrefabRefs(level.StartRooms) > 0) { return MausoleumCountValidModules(level) > 0; } return false; } private static int MausoleumCountValidModules(Level level) { return MausoleumCountValidPrefabRefs(level.ModulesNormal1) + MausoleumCountValidPrefabRefs(level.ModulesPassage1) + MausoleumCountValidPrefabRefs(level.ModulesDeadEnd1) + MausoleumCountValidPrefabRefs(level.ModulesExtraction1) + MausoleumCountValidPrefabRefs(level.ModulesNormal2) + MausoleumCountValidPrefabRefs(level.ModulesPassage2) + MausoleumCountValidPrefabRefs(level.ModulesDeadEnd2) + MausoleumCountValidPrefabRefs(level.ModulesExtraction2) + MausoleumCountValidPrefabRefs(level.ModulesNormal3) + MausoleumCountValidPrefabRefs(level.ModulesPassage3) + MausoleumCountValidPrefabRefs(level.ModulesDeadEnd3) + MausoleumCountValidPrefabRefs(level.ModulesExtraction3); } private static int MausoleumCountValidPrefabRefs(IEnumerable<PrefabRef>? prefabRefs) { if (prefabRefs == null) { return 0; } int num = 0; foreach (PrefabRef prefabRef in prefabRefs) { if (prefabRef != null && (!string.IsNullOrWhiteSpace(prefabRef.ResourcePath) || (Object)(object)prefabRef.Prefab != (Object)null)) { num++; } } return num; } internal static bool MausoleumIsCurrentLevel() { if (!MausoleumIsMausoleumLevel(((Object)(object)LevelGenerator.Instance != (Object)null) ? LevelGenerator.Instance.Level : null)) { return MausoleumIsMausoleumLevel(((Object)(object)RunManager.instance != (Object)null) ? RunManager.instance.levelCurrent : null); } return true; } internal static bool MausoleumIsMausoleumLevel(Level? level) { if ((Object)(object)level == (Object)null) { return false; } if (!string.Equals(((Object)level).name, "Mel Mausoleum", StringComparison.OrdinalIgnoreCase) && !string.Equals(level.ResourcePath, "Mausoleum", StringComparison.OrdinalIgnoreCase) && (string.IsNullOrWhiteSpace(((Object)level).name) || ((Object)level).name.IndexOf("mausoleum", StringComparison.OrdinalIgnoreCase) < 0)) { if (!string.IsNullOrWhiteSpace(level.ResourcePath)) { return level.ResourcePath.IndexOf("mausoleum", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } return true; } internal static void MausoleumEnsureLevelFallbackData(Level? level) { if (MausoleumIsMausoleumLevel(level)) { Level val = level; if (val.ValuablePresets == null) { val.ValuablePresets = new List<LevelValuables>(); } val = level; if (val.AmbiencePresets == null) { val.AmbiencePresets = new List<LevelAmbience>(); } if (level.ValuablePresets.Count == 0 && (Object)(object)ValuablePresets.GenericValuablePreset != (Object)null) { level.ValuablePresets.Add(ValuablePresets.GenericValuablePreset); } if (level.AmbiencePresets.Count == 0 && MausoleumTryGetFallbackAmbience(out LevelAmbience ambience)) { level.AmbiencePresets.Add(ambience); } } } private static bool MausoleumTryGetFallbackAmbience(out LevelAmbience ambience) { ambience = null; if ((Object)(object)AudioManager.instance != (Object)null && AudioManager.instance.levelAmbiences != null) { foreach (LevelAmbience levelAmbience in AudioManager.instance.levelAmbiences) { if (!((Object)(object)levelAmbience == (Object)null)) { ambience = levelAmbience; return true; } } } if ((Object)(object)RunManager.instance != (Object)null && RunManager.instance.levels != null) { foreach (Level level in RunManager.instance.levels) { if (level?.AmbiencePresets == null) { continue; } foreach (LevelAmbience ambiencePreset in level.AmbiencePresets) { if (!((Object)(object)ambiencePreset == (Object)null)) { ambience = ambiencePreset; return true; } } } } return false; } internal static void MausoleumEnsureExtractionPointCompatibility(ExtractionPoint extractionPoint) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Expected O, but got Unknown if ((Object)(object)extractionPoint == (Object)null || !MausoleumIsCurrentLevel()) { return; } if ((Object)(object)extractionPoint.extractionArea == (Object)null) { GameObject val = GameObject.CreatePrimitive((PrimitiveType)2); ((Object)val).name = "Mausoleum Patch Extraction Area"; val.transform.SetParent(((Component)extractionPoint).transform, false); val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; val.transform.localScale = Vector3.one * 0.1f; MeshRenderer component = val.GetComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null) { ((Renderer)component).enabled = false; } Collider component2 = val.GetComponent<Collider>(); if ((Object)(object)component2 != (Object)null) { Object.Destroy((Object)(object)component2); } val.SetActive(false); MausoleumApplyHideFlags((Object)(object)val); extractionPoint.extractionArea = val; } if ((Object)(object)extractionPoint.grossUp == (Object)null) { GameObject val2 = new GameObject("Mausoleum Patch GrossUp"); val2.transform.SetParent(((Component)extractionPoint).transform, false); val2.SetActive(false); MausoleumApplyHideFlags((Object)(object)val2); extractionPoint.grossUp = val2; } } internal void MausoleumRepairLevelPoints(LevelGenerator levelGenerator) { if ((Object)(object)levelGenerator == (Object)null || !MausoleumIsMausoleumLevel(levelGenerator.Level) || levelGenerator.LevelPathPoints == null) { return; } int num = 0; int num2 = 0; foreach (LevelPoint levelPathPoint in levelGenerator.LevelPathPoints) { if (MausoleumRepairLevelPoint(levelPathPoint)) { num++; } if (MausoleumRepairLevelPointRoom(levelPathPoint)) { num2++; } } if (num > 0 || num2 > 0) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Empress Mausoleum Compat Patch repaired {num} Mausoleum level points onto the navmesh and restored {num2} room links."); } } internal IEnumerator MausoleumStartRoomGeneration(LevelGenerator levelGenerator) { if ((Object)(object)levelGenerator == (Object)null) { yield break; } levelGenerator.waitingForSubCoroutine = true; levelGenerator.State = (LevelState)3; Level level = levelGenerator.Level; bool flag = MausoleumIsMausoleumLevel(level); if (flag) { MausoleumTryRepairLevel(level); } List<PrefabRef> list = new List<PrefabRef>(); if (level?.StartRooms != null) { list.AddRange(level.StartRooms.Where((PrefabRef prefabRef) => prefabRef != null && !string.IsNullOrWhiteSpace(prefabRef.ResourcePath))); } if (list.Count == 0 && flag && (Object)(object)level != (Object)null) { AssetBundle val = MausoleumGetBundle(); if ((Object)(object)val != (Object)null) { MausoleumPrefabBuckets mausoleumPrefabBuckets = MausoleumCollectPrefabs(val); if (mausoleumPrefabBuckets.StartRooms.Count > 0) { MausoleumRegisterLevelObjects(level); MausoleumApplyPrefabBuckets(level, mausoleumPrefabBuckets); list.AddRange(level.StartRooms.Where((PrefabRef prefabRef) => prefabRef != null && !string.IsNullOrWhiteSpace(prefabRef.ResourcePath))); } } } ListExtension.Shuffle<PrefabRef>((IList<PrefabRef>)list); if (levelGenerator.DebugStartRoom != null) { if (list.Count == 0) { list.Add(levelGenerator.DebugStartRoom); } else { list[0] = levelGenerator.DebugStartRoom; } } if (list.Count == 0) { ((BaseUnityPlugin)this).Logger.LogError((object)("Empress Mausoleum Compat Patch could not recover a valid start room for " + (((Object)(object)level != (Object)null) ? ((Object)level).name : "the current level") + ".")); levelGenerator.waitingForSubCoroutine = false; yield break; } PrefabRef val2 = list[0]; GameObject val3 = ((GameManager.instance.gameMode != 0) ? PhotonNetwork.InstantiateRoomObject(val2.ResourcePath, Vector3.zero, Quaternion.identity, (byte)0, (object[])null) : Object.Instantiate<GameObject>(val2.Prefab, Vector3.zero, Quaternion.identity)); if ((Object)(object)val3 != (Object)null && (Object)(object)levelGenerator.LevelParent != (Object)null) { val3.transform.parent = levelGenerator.LevelParent.transform; } yield return null; levelGenerator.waitingForSubCoroutine = false; } internal void MausoleumEnsureStartRoomList(LevelGenerator? levelGenerator) { if ((Object)(object)levelGenerator?.Level == (Object)null || (levelGenerator.Level.StartRooms != null && levelGenerator.Level.StartRooms.Count > 0)) { return; } MausoleumTryRepairLevel(levelGenerator.Level); if (levelGenerator.Level.StartRooms != null && levelGenerator.Level.StartRooms.Count > 0) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Empress Mausoleum Compat Patch populated {levelGenerator.Level.StartRooms.Count} start rooms for {((Object)levelGenerator.Level).name} before generation."); return; } AssetBundle val = MausoleumGetBundle(); if ((Object)(object)val == (Object)null) { return; } MausoleumPrefabBuckets mausoleumPrefabBuckets = MausoleumCollectPrefabs(val); if (mausoleumPrefabBuckets.StartRooms.Count != 0) { MausoleumEnsureLevelFallbackData(levelGenerator.Level); MausoleumRegisterLevelObjects(levelGenerator.Level); MausoleumApplyPrefabBuckets(levelGenerator.Level, mausoleumPrefabBuckets); if (levelGenerator.Level.StartRooms != null && levelGenerator.Level.StartRooms.Count > 0) { ((BaseUnityPlugin)this).Logger.LogInfo((object)$"Empress Mausoleum Compat Patch force-filled {levelGenerator.Level.StartRooms.Count} start rooms for {((Object)levelGenerator.Level).name} from the original bundle."); } } } internal static PrefabRef MausoleumGetSafeStartRoomRef(List<PrefabRef> startRooms, int index, object? stateMachine) { if (startRooms != null && index >= 0 && index < startRooms.Count) { PrefabRef val = startRooms[index]; if (val != null && !string.IsNullOrWhiteSpace(val.ResourcePath)) { return val; } } MausoleumCompatPatchPlugin instance = Instance; LevelGenerator val2 = MausoleumGetLevelGeneratorFromStateMachine(stateMachine); instance?.MausoleumEnsureStartRoomList(val2); if (val2?.Level?.StartRooms != null) { List<PrefabRef> list = val2.Level.StartRooms.Where((PrefabRef prefabRef) => prefabRef != null && !string.IsNullOrWhiteSpace(prefabRef.ResourcePath)).ToList(); if (index >= 0 && index < list.Count) { return list[index]; } if (list.Count > 0) { return list[0]; } } if ((Object)(object)instance != (Object)null && (Object)(object)val2?.Level != (Object)null) { AssetBundle val3 = instance.MausoleumGetBundle(); if ((Object)(object)val3 != (Object)null) { GameObject val4 = MausoleumCollectPrefabs(val3).StartRooms.FirstOrDefault(); if ((Object)(object)val4 != (Object)null) { PrefabRef val5 = MausoleumRegisterNetworkPrefab("Level/" + ((Object)val2.Level).name + "/StartRoom/" + ((Object)val4).name, val4); if (val5 != null) { return val5; } } } } throw new ArgumentOutOfRangeException("index", "Empress Mausoleum Compat Patch could not recover a valid start room."); } internal static bool MausoleumTryRecoverStartRoomFromListAccess(List<PrefabRef> startRooms, int index, ref PrefabRef __result) { if (startRooms == null || (index >= 0 && index < startRooms.Count)) { return true; } Level val = (((Object)(object)RunManager.instance != (Object)null) ? RunManager.instance.levelCurrent : null); if (!MausoleumIsMausoleumLevel(val)) { return true; } MausoleumCompatPatchPlugin? instance = Instance; LevelGenerator instance2 = LevelGenerator.Instance; instance?.MausoleumEnsureStartRoomList(instance2); instance?.MausoleumTryRepairLevel(val); Level val2 = instance2?.Level ?? val; if (val2?.StartRooms != null) { foreach (PrefabRef startRoom in val2.StartRooms) { if (startRoom != null && !string.IsNullOrWhiteSpace(startRoom.ResourcePath)) { MausoleumCompatPatchPlugin? instance3 = Instance; if (instance3 != null) { ((BaseUnityPlugin)instance3).Logger.LogInfo((object)("Empress Mausoleum Compat Patch recovered start room access for " + ((Object)val2).name + " during generation.")); } __result = startRoom; return false; } } } return true; } internal static LevelGenerator? MausoleumGetLevelGeneratorFromStateMachine(object? stateMachine) { if (stateMachine == null) { return null; } FieldInfo[] fields = stateMachine.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { if (typeof(LevelGenerator).IsAssignableFrom(fieldInfo.FieldType)) { object? value = fieldInfo.GetValue(stateMachine); LevelGenerator val = (LevelGenerator)((value is LevelGenerator) ? value : null); if (val != null) { return val; } } } return null; } private static bool MausoleumRepairLevelPoint(LevelPoint? levelPoint) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: 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_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)levelPoint == (Object)null) { return false; } Vector3 position = ((Component)levelPoint).transform.position; NavMeshHit val = default(NavMeshHit); if (NavMesh.SamplePosition(position, ref val, 0.5f, -1)) { return false; } NavMeshHit val2 = default(NavMeshHit); if (!NavMesh.SamplePosition(position, ref val2, 2f, -1)) { return false; } ((Component)levelPoint).transform.position = ((NavMeshHit)(ref val2)).position; MausoleumRepairLevelPointRoom(levelPoint); return true; } private static bool MausoleumRepairLevelPointRoom(LevelPoint? levelPoint) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)levelPoint == (Object)null || (Object)(object)levelPoint.Room != (Object)null) { return false; } RoomVolume room = default(RoomVolume); Vector3 val = default(Vector3); if (!SemiFunc.GetRoomVolumeAtPosition(((Component)levelPoint).transform.position, ref room, ref val)) { return false; } levelPoint.Room = room; return true; } internal IEnumerator MausoleumSilentLevelPointCheck(LevelPoint levelPoint) { if (!((Object)(object)levelPoint == (Object)null)) { while ((Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated) { yield return (object)new WaitForSeconds(0.1f); } yield return (object)new WaitForSeconds(0.5f); if (MausoleumIsCurrentLevel()) { MausoleumRepairLevelPoint(levelPoint); MausoleumRepairLevelPointRoom(levelPoint); MausoleumRepairLevelPointConnections(levelPoint, LevelGenerator.Instance?.LevelPathPoints); } } } private static void MausoleumRepairLevelPointConnections(LevelPoint? levelPoint, IList<LevelPoint>? allLevelPoints) { if ((Object)(object)levelPoint == (Object)null) { return; } if (levelPoint.ConnectedPoints == null) { levelPoint.ConnectedPoints = new List<LevelPoint>(); } levelPoint.ConnectedPoints.RemoveAll((LevelPoint connectedPoint) => (Object)(object)connectedPoint == (Object)null); LevelPoint[] array = levelPoint.ConnectedPoints.ToArray(); for (int i = 0; i < array.Length; i++) { MausoleumAddLevelPointConnection(array[i], levelPoint); } if (!levelPoint.ModuleConnect || allLevelPoints == null || levelPoint.ConnectedPoints.Count > 0) { return; } LevelPoint val = null; float currentBestDistance = float.MaxValue; foreach (LevelPoint allLevelPoint in allLevelPoints) { if (MausoleumCanConnectLevelPoints(levelPoint, allLevelPoint, currentBestDistance, out var distance)) { val = allLevelPoint; currentBestDistance = distance; } } MausoleumAddLevelPointConnection(levelPoint, val); MausoleumAddLevelPointConnection(val, levelPoint); } private static bool MausoleumCanConnectLevelPoints(LevelPoint source, LevelPoint? candidate, float currentBestDistance, out float distance) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) distance = 0f; if ((Object)(object)source == (Object)null || (Object)(object)candidate == (Object)null || (Object)(object)source == (Object)(object)candidate || !candidate.ModuleConnect) { return false; } Vector3 val = ((Component)source).transform.position - ((Component)candidate).transform.position; if (((Vector3)(ref val)).sqrMagnitude <= Mathf.Epsilon) { return false; } distance = ((Vector3)(ref val)).magnitude; if (distance >= 15f || distance >= currentBestDistance) { return false; } if (Vector3.Dot(((Component)candidate).transform.forward, ((Component)source).transform.forward) > -0.8f) { return false; } return Vector3.Dot(((Component)candidate).transform.forward, ((Vector3)(ref val)).normalized) > 0.8f; } private static void MausoleumAddLevelPointConnection(LevelPoint? source, LevelPoint? target) { if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null)) { if (source.ConnectedPoints == null) { source.ConnectedPoints = new List<LevelPoint>(); } if (!source.ConnectedPoints.Contains(target)) { source.ConnectedPoints.Add(target); } } } internal GameObject MausoleumCreateFallbackDoorMapObject(Map map, DirtFinderMapDoor door) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) MapLayer layerParent = map.GetLayerParent(((Component)door).transform.position.y); GameObject val = MausoleumInstantiateFallbackDoorMapObject(map, ((Component)layerParent).transform); ((Object)val).name = ((Object)((Component)door).gameObject).name; door.Target = val.transform; DirtFinderMapDoorTarget val2 = val.GetComponent<DirtFinderMapDoorTarget>() ?? val.AddComponent<DirtFinderMapDoorTarget>(); val2.Target = ((Component)door).transform; val2.Layer = layerParent; DirtFinderMapDoorTarget val3 = val2; if (val3.HingeTransform == null) { val3.HingeTransform = val.transform; } map.DoorUpdate(val2.HingeTransform, ((Component)door).transform, layerParent); if (!_mausoleumLoggedDoorMapFallback) { _mausoleumLoggedDoorMapFallback = true; ((BaseUnityPlugin)this).Logger.LogWarning((object)"Empress Mausoleum Compat Patch injected fallback minimap door markers for missing Mausoleum door prefabs."); } return val; } private static GameObject MausoleumInstantiateFallbackDoorMapObject(Map map, Transform parent) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) GameObject val; if ((Object)(object)map.Door1x1Object != (Object)null) { val = Object.Instantiate<GameObject>(map.Door1x1Object, parent); Collider[] componentsInChildren = val.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Object.Destroy((Object)(object)componentsInChildren[i]); } } else { val = GameObject.CreatePrimitive((PrimitiveType)3); val.transform.SetParent(parent, false); val.transform.localScale = new Vector3(0.12f, 0.12f, 0.3f); Collider component = val.GetComponent<Collider>(); if ((Object)(object)component != (Object)null) { Object.Destroy((Object)(object)component); } } val.transform.localPosition = Vector3.zero; val.transform.localRotation = Quaternion.identity; DirtFinderMapDoorTarget val2 = val.GetComponent<DirtFinderMapDoorTarget>() ?? val.AddComponent<DirtFinderMapDoorTarget>(); if (val2.HingeTransform == null) { val2.HingeTransform = val.transform; } MausoleumApplyHideFlags((Object)(object)val); return val; } private static void MausoleumApplyHideFlags(Object obj) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (obj == (Object)null) { return; } obj.hideFlags = (HideFlags)(obj.hideFlags | 0x23); GameObject val = (GameObject)(object)((obj is GameObject) ? obj : null); if (val == null) { return; } Transform[] componentsInChildren = val.GetComponentsInChildren<Transform>(true); foreach (Transform obj2 in componentsInChildren) { ((Object)obj2).hideFlags = (HideFlags)(((Object)obj2).hideFlags | 0x23); GameObject gameObject = ((Component)obj2).gameObject; ((Object)gameObject).hideFlags = (HideFlags)(((Object)gameObject).hideFlags | 0x23); Component[] components = ((Component)obj2).GetComponents<Component>(); foreach (Component val2 in components) { if ((Object)(object)val2 != (Object)null) { ((Object)val2).hideFlags = (HideFlags)(((Object)val2).hideFlags | 0x23); } } } } } [HarmonyPatch(typeof(LevelGenerator), "StartRoomGeneration")] internal static class MausoleumCompatPatchStartRoomGenerationPatch { [HarmonyPrefix] private static void MausoleumPrefix() { if (MausoleumCompatPatchPlugin.MausoleumIsCurrentLevel()) { MausoleumCompatPatchPlugin.Instance?.MausoleumTryRepairCurrentLevel(); } } } [HarmonyPatch] internal static class MausoleumCompatPatchStartRoomGenerationMoveNextPatch { private static MethodBase? TargetMethod() { MethodInfo methodInfo = AccessTools.Method(typeof(LevelGenerator), "StartRoomGeneration", (Type[])null, (Type[])null); if (!(methodInfo != null)) { return null; } return AccessTools.EnumeratorMoveNext((MethodBase)methodInfo); } [HarmonyPrefix] private static void MausoleumPrefix(object __instance) { MausoleumCompatPatchPlugin instance = MausoleumCompatPatchPlugin.Instance; if (!((Object)(object)instance == (Object)null)) { LevelGenerator levelGenerator = MausoleumCompatPatchPlugin.MausoleumGetLevelGeneratorFromStateMachine(__instance); instance.MausoleumEnsureStartRoomList(levelGenerator); } } [HarmonyTranspiler] private static IEnumerable<CodeInstruction> MausoleumTranspiler(IEnumerable<CodeInstruction> instructions) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Expected O, but got Unknown //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown MethodInfo methodInfo = AccessTools.Method(typeof(List<PrefabRef>), "get_Item", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(MausoleumCompatPatchPlugin), "MausoleumGetSafeStartRoomRef", (Type[])null, (Type[])null); if (methodInfo == null || methodInfo2 == null) { return instructions; } List<CodeInstruction> list = new List<CodeInstruction>(); foreach (CodeInstruction instruction in instructions) { if (CodeInstructionExtensions.Calls(instruction, methodInfo)) { list.Add(new CodeInstruction(OpCodes.Ldarg_0, (object)null)); list.Add(new CodeInstruction(OpCodes.Call, (object)methodInfo2)); } else { list.Add(instruction); } } return list; } } [HarmonyPatch] internal static class MausoleumCompatPatchGenerateMoveNextPatch { private static MethodBase? TargetMethod() { MethodInfo methodInfo = AccessTools.Method(typeof(LevelGenerator), "Generate", (Type[])null, (Type[])null); if (!(methodInfo != null)) { return null; } return AccessTools.EnumeratorMoveNext((MethodBase)methodInfo); } [HarmonyPrefix] private static void MausoleumPrefix(object __instance) { MausoleumCompatPatchPlugin instance = MausoleumCompatPatchPlugin.Instance; if (!((Object)(object)instance == (Object)null)) { LevelGenerator levelGenerator = MausoleumCompatPatchPlugin.MausoleumGetLevelGeneratorFromStateMachine(__instance); instance.MausoleumEnsureStartRoomList(levelGenerator); } } } [HarmonyPatch] internal static class MausoleumCompatPatchPrefabRefListGetItemPatch { private static MethodBase? TargetMethod() { return AccessTools.PropertyGetter(typeof(List<PrefabRef>), "Item"); } [HarmonyPrefix] private static bool MausoleumPrefix(List<PrefabRef> __instance, int index, ref PrefabRef __result) { return MausoleumCompatPatchPlugin.MausoleumTryRecoverStartRoomFromListAccess(__instance, index, ref __result); } } [HarmonyPatch(typeof(PhysGrabHinge), "Awake")] internal static class MausoleumCompatPatchPhysGrabHingeAwakePatch { [HarmonyPrefix] private static void MausoleumPrefix(PhysGrabHinge __instance) { if (MausoleumCompatPatchPlugin.MausoleumIsCurrentLevel()) { MausoleumCompatPatchPlugin.MausoleumEnsurePhysGrabHingeCompatibility(__instance); } } } [HarmonyPatch(typeof(ExtractionPoint), "Start")] internal static class MausoleumCompatPatchExtractionPointStartPatch { [HarmonyPostfix] private static void MausoleumPostfix(ExtractionPoint __instance) { MausoleumCompatPatchPlugin.MausoleumEnsureExtractionPointCompatibility(__instance); } } [HarmonyPatch(typeof(Levels), "RegisterLevelWithGame")] internal static class MausoleumCompatPatchRegisterLevelPatch { [HarmonyPrefix] private static void MausoleumPrefix(Level level) { MausoleumCompatPatchPlugin.MausoleumEnsureLevelFallbackData(level); MausoleumCompatPatchPlugin.Instance?.MausoleumTryRepairLevel(level); } } [HarmonyPatch(typeof(Map), "AddDoor")] internal static class MausoleumCompatPatchMapAddDoorPatch { [HarmonyPrefix] private static bool MausoleumPrefix(Map __instance, DirtFinderMapDoor door, GameObject doorPrefab, ref GameObject __result) { if (!MausoleumCompatPatchPlugin.MausoleumIsCurrentLevel() || (Object)(object)door == (Object)null || (Object)(object)doorPrefab != (Object)null) { return true; } MausoleumCompatPatchPlugin instance = MausoleumCompatPatchPlugin.Instance; if ((Object)(object)instance == (Object)null) { return true; } __result = instance.MausoleumCreateFallbackDoorMapObject(__instance, door); return false; } } [HarmonyPatch(typeof(LevelGenerator), "NavMeshSetupRPC")] internal static class MausoleumCompatPatchNavMeshSetupPatch { [HarmonyPostfix] private static void MausoleumPostfix(LevelGenerator __instance) { MausoleumCompatPatchPlugin.Instance?.MausoleumRepairLevelPoints(__instance); } } [HarmonyPatch(typeof(LevelPoint), "NavMeshCheck")] internal static class MausoleumCompatPatchLevelPointNavMeshCheckPatch { [HarmonyPrefix] private static bool MausoleumPrefix(LevelPoint __instance, ref IEnumerator __result) { if (!MausoleumCompatPatchPlugin.MausoleumIsCurrentLevel()) { return true; } MausoleumCompatPatchPlugin instance = MausoleumCompatPatchPlugin.Instance; if ((Object)(object)instance == (Object)null) { return true; } __result = instance.MausoleumSilentLevelPointCheck(__instance); return false; } } }