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 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 StartRooms { get; set; } = new List(); public List Normal1 { get; set; } = new List(); public List Passage1 { get; set; } = new List(); public List DeadEnd1 { get; set; } = new List(); public List Extraction1 { get; set; } = new List(); public List Normal2 { get; set; } = new List(); public List Passage2 { get; set; } = new List(); public List DeadEnd2 { get; set; } = new List(); public List Extraction2 { get; set; } = new List(); public List Normal3 { get; set; } = new List(); public List Passage3 { get; set; } = new List(); public List DeadEnd3 { get; set; } = new List(); public List Extraction3 { get; set; } = new List(); 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(); private static readonly string[] MausoleumExtraction2Names = Array.Empty(); private static readonly string[] MausoleumNormal3Names = new string[2] { "MausoleumNorm4", "MausoleumNorm6" }; private static readonly string[] MausoleumPassage3Names = Array.Empty(); private static readonly string[] MausoleumDeadEnd3Names = Array.Empty(); private static readonly string[] MausoleumExtraction3Names = Array.Empty(); 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 list = new List(); 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?)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? 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? 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 prefabsByName = new Dictionary(StringComparer.OrdinalIgnoreCase); StartRoom[] array = bundle.LoadAllAssets(); foreach (StartRoom val in array) { MausoleumAddAssetByName(prefabsByName, ((Object)(object)val != (Object)null) ? ((Component)val).gameObject : null); } Module[] array2 = bundle.LoadAllAssets(); foreach (Module val2 in array2) { MausoleumAddAssetByName(prefabsByName, ((Object)(object)val2 != (Object)null) ? ((Component)val2).gameObject : null); } GameObject[] array3 = bundle.LoadAllAssets(); 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 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(); 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(); 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(); 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 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 MausoleumResolvePrefabs(IReadOnlyDictionary prefabsByName, IEnumerable names) { List list = new List(); 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(); 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(); 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 MausoleumRegisterPrefabs(Level level, string moduleTypeName, IEnumerable prefabs) { List list = new List(); foreach (GameObject item in prefabs.OrderBy((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(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(true); foreach (NotValuableObject val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val.physAttributePreset != (Object)null)) { Rigidbody component = ((Component)val).GetComponent(); 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(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() ?? ((Component)hinge).gameObject.AddComponent(); } 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(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)hinge).gameObject.AddComponent(); } ((Joint)val2).autoConfigureConnectedAnchor = true; ((Joint)val2).axis = Vector3.right; if ((Object)(object)((Component)hinge).GetComponent() == (Object)null) { ((Component)hinge).gameObject.AddComponent(); } 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(); } val = hinge; if (val.wallTagObjects == null) { val.wallTagObjects = Array.Empty(); } val = hinge; if (val.lowPassTriggers == null) { val.lowPassTriggers = Array.Empty(); } } } 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)((Component)hinge2).GetComponentsInChildren(true)).FirstOrDefault((Func)((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(); 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(); } val = sound; if (val.LowPassIgnoreColliders == null) { val.LowPassIgnoreColliders = new List(); } } } private static PhysAttribute MausoleumCreateFallbackPhysAttribute(float mass) { PhysAttribute obj = ScriptableObject.CreateInstance(); 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? 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(); } val = level; if (val.AmbiencePresets == null) { val.AmbiencePresets = new List(); } 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(); if ((Object)(object)component != (Object)null) { ((Renderer)component).enabled = false; } Collider component2 = val.GetComponent(); 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 list = new List(); 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((IList)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(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 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 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 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? allLevelPoints) { if ((Object)(object)levelPoint == (Object)null) { return; } if (levelPoint.ConnectedPoints == null) { levelPoint.ConnectedPoints = new List(); } 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(); } 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() ?? val.AddComponent(); 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(map.Door1x1Object, parent); Collider[] componentsInChildren = val.GetComponentsInChildren(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(); 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() ?? val.AddComponent(); 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(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(); 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 MausoleumTranspiler(IEnumerable 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), "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 list = new List(); 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), "Item"); } [HarmonyPrefix] private static bool MausoleumPrefix(List __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; } } }