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 Empress Mausoleum Compat Patch v3.5.0
MausoleumCompatPatch.dll
Decompiled a month 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 REPOLib; using REPOLib.Modules; using Unity.AI.Navigation; using UnityEngine; using UnityEngine.AI; using UnityEngine.Audio; using UnityEngine.SceneManagement; using UnityEngine.UI; [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.15.0")] [assembly: AssemblyInformationalVersion("1.0.15")] [assembly: AssemblyProduct("MausoleumCompatPatch")] [assembly: AssemblyTitle("MausoleumCompatPatch")] [assembly: AssemblyVersion("1.0.15.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.15")] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class MausoleumCompatPatchPlugin : BaseUnityPlugin { private sealed class MausoleumLoadingGraphic { public AssetBundle Bundle { get; } public Sprite Sprite { get; } public string ResourcePath { get; } public bool CanUsePrefabRef { get; } public MausoleumLoadingGraphic(AssetBundle bundle, Sprite sprite, string resourcePath, bool canUsePrefabRef) { Bundle = bundle; Sprite = sprite; ResourcePath = resourcePath; CanUsePrefabRef = canUsePrefabRef; } } 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.15"; 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 const int MausoleumVehicleVolumeCount = 4; private const float MausoleumVehicleVolumeSideOffset = 2f; private const float MausoleumVehicleVolumeForwardOffset = 2.5f; private const float MausoleumVehicleVolumeForwardSpacing = 2f; private const float MausoleumChargingStationForwardOffset = 6.5f; private static readonly string[] MausoleumLoadingGraphicFieldNames = new string[3] { "LoadingGraphic01", "LoadingGraphic02", "LoadingGraphic03" }; private static readonly string[] MausoleumPreferredLoadingGraphicNames = new string[3] { "MausoleumLoad0", "MausoleumLoad1", "MausoleumLoad2" }; private static readonly List<Sprite> MausoleumLoadingSprites = new List<Sprite>(); 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 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) { return; } _mausoleumRepairQueued = true; try { MausoleumTryRepairLevel(); } finally { _mausoleumRepairQueued = false; } } 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)) { AssetBundle val = MausoleumGetBundle(); if ((Object)(object)val != (Object)null) { MausoleumEnsureLevelLoadingGraphics(level, val); } _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)) { AssetBundle val2 = MausoleumGetBundle(); if ((Object)(object)val2 != (Object)null) { MausoleumEnsureLevelLoadingGraphics(val, val2); } _mausoleumRepairApplied = true; return true; } AssetBundle val3 = MausoleumGetBundle(); if ((Object)(object)val3 == (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(val3); 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)val3); MausoleumApplyHideFlags((Object)(object)val); MausoleumEnsureLevelFallbackData(val); MausoleumEnsureLevelLoadingGraphics(val, val3); 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)) { AssetBundle val = MausoleumGetBundle(); if ((Object)(object)val != (Object)null) { MausoleumEnsureLevelLoadingGraphics(level, val); } _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 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)level); MausoleumEnsureLevelFallbackData(level); MausoleumEnsureLevelLoadingGraphics(level, val2); 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 (level.ConnectObject != null) { GameObject val = MausoleumResolvePrefab(level.ConnectObject); if ((Object)(object)val != (Object)null) { MausoleumRegisterNetworkPrefab("Level/" + MausoleumGetLevelPath(level) + "/Other/" + MausoleumGetPrefabName(level.ConnectObject, val), val); } } if (level.BlockObject != null) { GameObject val2 = MausoleumResolvePrefab(level.BlockObject); if ((Object)(object)val2 != (Object)null) { MausoleumRegisterNetworkPrefab("Level/" + MausoleumGetLevelPath(level) + "/Other/" + MausoleumGetPrefabName(level.BlockObject, val2), val2); } } } private static string MausoleumGetLevelPath(Level level) { if (!string.IsNullOrWhiteSpace(((Object)level).name)) { return ((Object)level).name; } return "Mausoleum"; } private static string MausoleumGetPrefabName(PrefabRef prefabRef, GameObject prefab) { if (!string.IsNullOrWhiteSpace(prefabRef.PrefabName)) { return prefabRef.PrefabName; } return ((Object)prefab).name; } private static GameObject? MausoleumResolvePrefab(PrefabRef? prefabRef) { if (prefabRef == null) { return null; } if (prefabRef.IsValid()) { return prefabRef.Prefab; } AssetBundle bundle = prefabRef.Bundle; if ((Object)(object)bundle == (Object)null || string.IsNullOrWhiteSpace(prefabRef.PrefabName)) { return null; } GameObject[] array = bundle.LoadAllAssets<GameObject>(); foreach (GameObject val in array) { if ((Object)(object)val != (Object)null && string.Equals(((Object)val).name, prefabRef.PrefabName, StringComparison.OrdinalIgnoreCase)) { return val; } } return null; } 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, prefab); if (val != null) { return val; } MausoleumPreparePrefab(prefab); Utilities.FixAudioMixerGroups(prefab); return NetworkPrefabs.RegisterNetworkPrefab(prefabId, prefab); } private static PrefabRef? MausoleumGetRegisteredPrefabRef(string prefabId, GameObject prefab) { if (!NetworkPrefabs.PrefabRefs.TryGetValue(prefabId, out var value) || value == null) { return null; } if ((Object)(object)value.Prefab == (Object)null || (Object)(object)value.Prefab == (Object)(object)prefab) { return value; } return null; } private static void MausoleumPreparePrefab(GameObject prefab) { MausoleumApplyHideFlags((Object)(object)prefab); MausoleumEnsureVehicleSupport(prefab); MausoleumNormalizeBoxColliderSizes(prefab); MausoleumIgnoreUnreadableMeshesForNavMesh(prefab); MausoleumAssignFallbackAudioMixerGroups(prefab); MausoleumAssignFallbackPhysAttributes(prefab); MausoleumAssignFallbackHingeData(prefab); } private static void MausoleumEnsureVehicleSupport(GameObject prefab) { if (!((Object)(object)prefab == (Object)null) && MausoleumIsStartRoomPrefab(prefab)) { MausoleumEnsureVehicleItemVolumes(prefab); MausoleumEnsureVehicleChargingStation(prefab); } } private static bool MausoleumIsStartRoomPrefab(GameObject prefab) { GameObject prefab2 = prefab; if (!((Object)(object)prefab2.GetComponentInChildren<StartRoom>(true) != (Object)null)) { return MausoleumStartRoomNames.Any((string name) => string.Equals(((Object)prefab2).name, name, StringComparison.OrdinalIgnoreCase)); } return true; } private static void MausoleumEnsureVehicleItemVolumes(GameObject prefab) { int num = prefab.GetComponentsInChildren<ItemVolume>(true).Count(MausoleumIsVehicleItemVolume); if (num < 4) { Transform parent = MausoleumFindOrCreateVehicleSupportRoot(prefab); Transform anchor = MausoleumFindTruckAnchor(prefab); for (int i = num; i < 4; i++) { MausoleumCreateVehicleItemVolume(parent, anchor, i); } } } private static bool MausoleumIsVehicleItemVolume(ItemVolume itemVolume) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 return (int)MausoleumGetComponentField<itemVolume>((Component)(object)itemVolume, "itemVolume", (itemVolume)0) == 9; } private static void MausoleumCreateVehicleItemVolume(Transform parent, Transform anchor, int index) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_003c: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject((index == 0) ? "Item Volume vehicle" : $"Item Volume vehicle ({index})"); val.SetActive(false); val.transform.SetParent(parent, false); val.transform.SetPositionAndRotation(MausoleumGetVehicleVolumePosition(anchor, index), anchor.rotation); ItemVolume target = val.AddComponent<ItemVolume>(); MausoleumSetComponentField((Component)(object)target, "itemVolume", (object)(itemVolume)9); GameObject val2 = new GameObject("Vehicle"); val2.transform.SetParent(val.transform, false); val2.transform.localPosition = Vector3.zero; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = new Vector3(2.6f, 1.4f, 4f); MausoleumSetComponentField((Component)(object)target, "volumes", new List<GameObject> { val2 }); MausoleumApplyHideFlags((Object)(object)val); } private static Vector3 MausoleumGetVehicleVolumePosition(Transform anchor, int index) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: 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_005a: Unknown result type (might be due to invalid IL or missing references) float num = ((index % 2 == 0) ? (-2f) : 2f); float num2 = 2.5f + (float)(index / 2) * 2f; return anchor.position + anchor.right * num + anchor.forward * num2 + Vector3.up * 0.25f; } private static Transform MausoleumFindTruckAnchor(GameObject prefab) { LevelPoint[] componentsInChildren = prefab.GetComponentsInChildren<LevelPoint>(true); foreach (LevelPoint val in componentsInChildren) { if ((Object)(object)val != (Object)null && MausoleumGetComponentField((Component)(object)val, "Truck", fallback: false)) { return ((Component)val).transform; } } RoomVolume[] componentsInChildren2 = prefab.GetComponentsInChildren<RoomVolume>(true); foreach (RoomVolume val2 in componentsInChildren2) { if ((Object)(object)val2 != (Object)null && MausoleumGetComponentField((Component)(object)val2, "Truck", fallback: false)) { return ((Component)val2).transform; } } return prefab.transform; } private static Transform MausoleumFindOrCreateVehicleSupportRoot(GameObject prefab) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown Transform val = ((IEnumerable<Transform>)prefab.GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform child) => (Object)(object)child != (Object)null && string.Equals(((Object)child).name, "Empress Vehicle Support", StringComparison.OrdinalIgnoreCase))); if ((Object)(object)val != (Object)null) { return val; } GameObject val2 = new GameObject("Empress Vehicle Support"); val2.transform.SetParent(prefab.transform, false); MausoleumApplyHideFlags((Object)val2); return val2.transform; } private static void MausoleumEnsureVehicleChargingStation(GameObject prefab) { //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) if (prefab.GetComponentsInChildren<ChargingStation>(true).Any(MausoleumIsVehicleChargingStation)) { return; } ChargingStation val = MausoleumFindFallbackChargingStationTemplate(); if (!((Object)(object)val == (Object)null) && MausoleumIsVehicleChargingStation(val)) { ChargingStation val2 = MausoleumFindLegacyChargingStation(prefab); Transform val3 = MausoleumFindOrCreateVehicleSupportRoot(prefab); Transform val4 = MausoleumFindTruckAnchor(prefab); GameObject val5 = MausoleumCloneInactiveChargingStationTemplate(val); ((Object)val5).name = "Charging Station New"; val5.transform.SetParent(val3, false); if ((Object)(object)val2 != (Object)null) { val5.transform.SetPositionAndRotation(((Component)val2).transform.position, ((Component)val2).transform.rotation); ((Component)val2).gameObject.SetActive(false); } else { val5.transform.SetPositionAndRotation(val4.position + val4.forward * 6.5f + Vector3.up * 0.05f, Quaternion.LookRotation(-val4.forward, Vector3.up)); } Transform val6 = MausoleumFindChildByExactName(val5.transform, "Charge Area"); if ((Object)(object)val6 != (Object)null) { val6.localScale = new Vector3(Mathf.Max(val6.localScale.x, 4f), Mathf.Max(val6.localScale.y, 2f), Mathf.Max(val6.localScale.z, 4f)); } MausoleumApplyHideFlags((Object)(object)val5); Utilities.FixAudioMixerGroups(val5); } } private static GameObject MausoleumCloneInactiveChargingStationTemplate(ChargingStation template) { GameObject gameObject = ((Component)template).gameObject; bool activeSelf = gameObject.activeSelf; try { if (activeSelf) { gameObject.SetActive(false); } GameObject obj = Object.Instantiate<GameObject>(gameObject); obj.SetActive(false); return obj; } finally { if ((Object)(object)gameObject != (Object)null && activeSelf) { gameObject.SetActive(true); } } } internal static void MausoleumActivateVehicleChargingStation(StartRoom? startRoom) { if ((Object)(object)startRoom == (Object)null || !MausoleumIsCurrentLevel() || !MausoleumIsStartRoomPrefab(((Component)startRoom).gameObject)) { return; } ChargingStation[] componentsInChildren = ((Component)startRoom).GetComponentsInChildren<ChargingStation>(true); foreach (ChargingStation val in componentsInChildren) { if ((Object)(object)val != (Object)null && MausoleumIsVehicleChargingStation(val) && string.Equals(((Object)((Component)val).gameObject).name, "Charging Station New", StringComparison.OrdinalIgnoreCase) && !((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(true); } } ItemVolume[] componentsInChildren2 = ((Component)startRoom).GetComponentsInChildren<ItemVolume>(true); foreach (ItemVolume val2 in componentsInChildren2) { if ((Object)(object)val2 != (Object)null && MausoleumIsVehicleItemVolume(val2) && !((Component)val2).gameObject.activeSelf) { ((Component)val2).gameObject.SetActive(true); } } } private static ChargingStation? MausoleumFindFallbackChargingStationTemplate() { ChargingStation val = MausoleumFindChargingStationTemplateFromLevels(); if ((Object)(object)val != (Object)null && MausoleumIsVehicleChargingStation(val)) { return val; } return Resources.FindObjectsOfTypeAll<ChargingStation>().Where(delegate(ChargingStation candidate) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)candidate != (Object)null) { Scene scene = ((Component)candidate).gameObject.scene; return !((Scene)(ref scene)).IsValid(); } return false; }).OrderByDescending(MausoleumIsVehicleChargingStation) .FirstOrDefault() ?? val; } private static ChargingStation? MausoleumFindChargingStationTemplateFromLevels() { ChargingStation val = null; if (RunManager.instance?.levels == null) { return val; } foreach (Level level in RunManager.instance.levels) { if ((Object)(object)level == (Object)null || MausoleumIsMausoleumLevel(level) || level.StartRooms == null) { continue; } foreach (PrefabRef startRoom in level.StartRooms) { GameObject val2 = null; try { val2 = MausoleumResolvePrefab(startRoom); } catch { } if ((Object)(object)val2 == (Object)null) { continue; } ChargingStation[] componentsInChildren = val2.GetComponentsInChildren<ChargingStation>(true); foreach (ChargingStation val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)null)) { if (MausoleumIsVehicleChargingStation(val3)) { return val3; } if (val == null) { val = val3; } } } } } return val; } private static ChargingStation? MausoleumFindLegacyChargingStation(GameObject prefab) { return ((IEnumerable<ChargingStation>)prefab.GetComponentsInChildren<ChargingStation>(true)).FirstOrDefault((Func<ChargingStation, bool>)((ChargingStation candidate) => (Object)(object)candidate != (Object)null && !MausoleumIsVehicleChargingStation(candidate))); } private static bool MausoleumIsVehicleChargingStation(ChargingStation? chargingStation) { if ((Object)(object)chargingStation == (Object)null) { return false; } Transform transform = ((Component)chargingStation).transform; if ((Object)(object)MausoleumFindChildByExactName(transform, "Charge Area") != (Object)null) { return (Object)(object)MausoleumFindChildByExactName(transform, "Line Between Two Points") != (Object)null; } return false; } private static Transform? MausoleumFindChildByExactName(Transform root, string name) { string name2 = name; return ((IEnumerable<Transform>)((Component)root).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform child) => (Object)(object)child != (Object)null && string.Equals(((Object)child).name, name2, StringComparison.OrdinalIgnoreCase))); } private static T MausoleumGetComponentField<T>(Component target, string fieldName, T fallback) { if ((Object)(object)target == (Object)null) { return fallback; } try { if (AccessTools.Field(((object)target).GetType(), fieldName) == null) { return fallback; } return (T)((Traverse.Create((object)target).Field(fieldName).GetValue() is T val) ? ((object)val) : ((object)fallback)); } catch { return fallback; } } private static void MausoleumSetComponentField(Component target, string fieldName, object value) { if ((Object)(object)target == (Object)null) { return; } try { if (!(AccessTools.Field(((object)target).GetType(), fieldName) == null)) { Traverse.Create((object)target).Field(fieldName).SetValue(value); } } catch { } } private static void MausoleumNormalizeBoxColliderSizes(GameObject prefab) { //IL_0024: 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_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0037: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)prefab == (Object)null) { return; } BoxCollider[] componentsInChildren = prefab.GetComponentsInChildren<BoxCollider>(true); Vector3 val2 = default(Vector3); foreach (BoxCollider val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { Vector3 size = val.size; ((Vector3)(ref val2))..ctor(Mathf.Abs(size.x), Mathf.Abs(size.y), Mathf.Abs(size.z)); if (size != val2) { val.size = val2; } } } } private static void MausoleumIgnoreUnreadableMeshesForNavMesh(GameObject prefab) { if ((Object)(object)prefab == (Object)null) { return; } MeshFilter[] componentsInChildren = prefab.GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val in componentsInChildren) { if (!((Object)(object)((val != null) ? val.sharedMesh : null) == (Object)null) && !MausoleumMeshIsReadable(val.sharedMesh)) { MausoleumIgnoreObjectFromNavMeshBuild(((Component)val).gameObject); } } SkinnedMeshRenderer[] componentsInChildren2 = prefab.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val2 in componentsInChildren2) { if (!((Object)(object)((val2 != null) ? val2.sharedMesh : null) == (Object)null) && !MausoleumMeshIsReadable(val2.sharedMesh)) { MausoleumIgnoreObjectFromNavMeshBuild(((Component)val2).gameObject); } } } private static bool MausoleumMeshIsReadable(Mesh mesh) { try { return mesh.isReadable; } catch { return false; } } private static void MausoleumIgnoreObjectFromNavMeshBuild(GameObject gameObject) { if (!((Object)(object)gameObject == (Object)null)) { NavMeshModifier obj = gameObject.GetComponent<NavMeshModifier>() ?? gameObject.AddComponent<NavMeshModifier>(); obj.ignoreFromBuild = true; obj.applyToChildren = false; } } 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 && prefabRef.IsValid()) { 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.IsNullOrWhiteSpace(((Object)level).name) || ((Object)level).name.IndexOf("mausoleum", StringComparison.OrdinalIgnoreCase) < 0)) { if (!string.IsNullOrWhiteSpace(level.NarrativeName)) { return level.NarrativeName.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 void MausoleumEnsureLevelLoadingGraphics(Level level, AssetBundle bundle) { List<MausoleumLoadingGraphic> list = MausoleumCollectLoadingGraphics(bundle); MausoleumCacheLoadingSprites(list); string[] mausoleumLoadingGraphicFieldNames = MausoleumLoadingGraphicFieldNames; foreach (string text in mausoleumLoadingGraphicFieldNames) { if (list.Count != 0 || !MausoleumLevelLoadingGraphicValid(level, text)) { MausoleumLoadingGraphic mausoleumLoadingGraphic = ((list.Count > 0) ? list[Math.Min(Array.IndexOf(MausoleumLoadingGraphicFieldNames, text), list.Count - 1)] : null); if (mausoleumLoadingGraphic == null || !MausoleumSetLevelLoadingGraphic(level, text, mausoleumLoadingGraphic)) { MausoleumCopyFallbackLevelLoadingGraphic(level, text); } } } } private static List<MausoleumLoadingGraphic> MausoleumCollectLoadingGraphics(AssetBundle bundle) { List<MausoleumLoadingGraphic> list = new List<MausoleumLoadingGraphic>(); HashSet<string> hashSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase); List<Sprite> source = (from sprite in bundle.LoadAllAssets<Sprite>() where (Object)(object)sprite != (Object)null && !string.IsNullOrWhiteSpace(((Object)sprite).name) select sprite).ToList(); string[] mausoleumPreferredLoadingGraphicNames = MausoleumPreferredLoadingGraphicNames; foreach (string preferredName in mausoleumPreferredLoadingGraphicNames) { Sprite val = ((IEnumerable<Sprite>)source).FirstOrDefault((Func<Sprite, bool>)((Sprite candidate) => string.Equals(((Object)candidate).name, preferredName, StringComparison.OrdinalIgnoreCase))); if (!((Object)(object)val == (Object)null) && hashSet.Add(((Object)val).name)) { bool canUsePrefabRef = (Object)(object)bundle.LoadAsset<Sprite>(((Object)val).name) != (Object)null; list.Add(new MausoleumLoadingGraphic(bundle, val, ((Object)val).name, canUsePrefabRef)); } } foreach (string item in bundle.GetAllAssetNames().OrderBy(MausoleumLoadingGraphicRank).ThenBy<string, string>((string name) => name, StringComparer.OrdinalIgnoreCase)) { Sprite val2 = bundle.LoadAsset<Sprite>(item); if (!((Object)(object)val2 == (Object)null) && hashSet.Add(item)) { list.Add(new MausoleumLoadingGraphic(bundle, val2, item, canUsePrefabRef: true)); } } foreach (Sprite item2 in source.OrderBy((Sprite sprite) => MausoleumLoadingGraphicRank(((Object)sprite).name)).ThenBy<Sprite, string>((Sprite sprite) => ((Object)sprite).name, StringComparer.OrdinalIgnoreCase)) { if (!((Object)(object)item2 == (Object)null) && !string.IsNullOrWhiteSpace(((Object)item2).name) && hashSet.Add(((Object)item2).name)) { bool canUsePrefabRef2 = (Object)(object)bundle.LoadAsset<Sprite>(((Object)item2).name) != (Object)null; list.Add(new MausoleumLoadingGraphic(bundle, item2, ((Object)item2).name, canUsePrefabRef2)); } } return list; } private static void MausoleumCacheLoadingSprites(IEnumerable<MausoleumLoadingGraphic> graphics) { MausoleumLoadingSprites.Clear(); foreach (MausoleumLoadingGraphic graphic in graphics) { if ((Object)(object)graphic.Sprite != (Object)null && !MausoleumLoadingSprites.Contains(graphic.Sprite)) { MausoleumLoadingSprites.Add(graphic.Sprite); } if (MausoleumLoadingSprites.Count >= MausoleumLoadingGraphicFieldNames.Length) { break; } } } internal static void MausoleumApplyLoadingGraphics(LoadingUI? loadingUI) { if (!((Object)(object)loadingUI == (Object)null) && MausoleumIsCurrentLevel() && MausoleumLoadingSprites.Count != 0) { MausoleumApplyLoadingGraphic(loadingUI.loadingGraphic01, 0); MausoleumApplyLoadingGraphic(loadingUI.loadingGraphic02, 1); MausoleumApplyLoadingGraphic(loadingUI.loadingGraphic03, 2); } } private static void MausoleumApplyLoadingGraphic(Image? image, int index) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)image == (Object)null)) { Sprite sprite = MausoleumLoadingSprites[Math.Min(index, MausoleumLoadingSprites.Count - 1)]; image.sprite = sprite; ((Graphic)image).color = Color.white; } } private static int MausoleumLoadingGraphicRank(string value) { if (string.IsNullOrWhiteSpace(value)) { return 1000; } string text = value.ToLowerInvariant(); int num = 0; if (text.Contains("loading") || text.Contains("load")) { num -= 100; } if (text.Contains("graphic")) { num -= 50; } if (text.Contains("mausoleum")) { num -= 25; } if (text.Contains("icon") || text.Contains("emoji")) { num += 100; } return num; } private static bool MausoleumLevelLoadingGraphicValid(Level level, string fieldName) { try { if (AccessTools.Field(((object)level).GetType(), fieldName) == null) { return false; } object value = Traverse.Create((object)level).Field(fieldName).GetValue(); if (value == null) { return false; } Sprite val = (Sprite)((value is Sprite) ? value : null); if (val != null) { return (Object)(object)val != (Object)null; } return AccessTools.Method(value.GetType(), "IsValid", Type.EmptyTypes, (Type[])null) != null && Traverse.Create(value).Method("IsValid", Array.Empty<object>()).GetValue<bool>(); } catch { return false; } } private static bool MausoleumSetLevelLoadingGraphic(Level level, string fieldName, MausoleumLoadingGraphic graphic) { try { FieldInfo fieldInfo = AccessTools.Field(((object)level).GetType(), fieldName); if (fieldInfo == null) { return false; } if (typeof(Sprite).IsAssignableFrom(fieldInfo.FieldType)) { Traverse.Create((object)level).Field(fieldName).SetValue((object)graphic.Sprite); return true; } if (!fieldInfo.FieldType.Name.StartsWith("PrefabRef", StringComparison.Ordinal)) { return false; } if (!graphic.CanUsePrefabRef) { return false; } object obj = Traverse.Create((object)level).Field(fieldName).GetValue() ?? AccessTools.CreateInstance(fieldInfo.FieldType); if (obj == null) { return false; } if (AccessTools.Method(fieldInfo.FieldType, "SetPrefab", new Type[2] { typeof(AssetBundle), typeof(string) }, (Type[])null) != null) { Traverse.Create(obj).Method("SetPrefab", new object[2] { graphic.Bundle, graphic.ResourcePath }).GetValue(); } else { if (AccessTools.Field(fieldInfo.FieldType, "bundle") != null) { Traverse.Create(obj).Field("bundle").SetValue((object)graphic.Bundle); } if (AccessTools.Field(fieldInfo.FieldType, "resourcePath") != null) { Traverse.Create(obj).Field("resourcePath").SetValue((object)graphic.ResourcePath); } if (AccessTools.Field(fieldInfo.FieldType, "prefabName") != null) { Traverse.Create(obj).Field("prefabName").SetValue((object)Path.GetFileNameWithoutExtension(graphic.ResourcePath)); } } Traverse.Create((object)level).Field(fieldName).SetValue(obj); return MausoleumLevelLoadingGraphicValid(level, fieldName); } catch { return false; } } private static bool MausoleumCopyFallbackLevelLoadingGraphic(Level level, string fieldName) { if (RunManager.instance?.levels == null) { return false; } foreach (Level level2 in RunManager.instance.levels) { if ((Object)(object)level2 == (Object)null || (Object)(object)level2 == (Object)(object)level) { continue; } try { FieldInfo fieldInfo = AccessTools.Field(((object)level2).GetType(), fieldName); FieldInfo fieldInfo2 = AccessTools.Field(((object)level).GetType(), fieldName); if (fieldInfo == null || fieldInfo2 == null) { continue; } object value = Traverse.Create((object)level2).Field(fieldName).GetValue(); if (value != null) { Traverse.Create((object)level).Field(fieldName).SetValue(value); if (MausoleumLevelLoadingGraphicValid(level, fieldName)) { return true; } } } catch { } } return false; } 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 bool MausoleumShouldSuppressUnityLog(LogType logType, string? format, object[]? args) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if (!MausoleumIsCurrentLevel()) { return false; } string text = MausoleumFormatUnityLogMessage(format, args); if (string.IsNullOrWhiteSpace(text)) { return false; } if ((int)logType == 2 && text.StartsWith("BoxCollider does not support negative scale or size.", StringComparison.Ordinal)) { return true; } if ((int)logType == 0 && text.StartsWith("RuntimeNavMeshBuilder: Source mesh ", StringComparison.Ordinal) && text.IndexOf("does not allow read access", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } if ((int)logType == 0) { if (!text.StartsWith("Level Point: ", StringComparison.Ordinal)) { return text.StartsWith(" Point Name: ", StringComparison.Ordinal); } return true; } return false; } private static string MausoleumFormatUnityLogMessage(string? format, object[]? args) { if (format == null) { return string.Empty; } if (args == null || args.Length == 0) { return format; } try { return string.Format(format, args); } catch { return format; } } 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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; } MausoleumHideExtractionAreaVisual(extractionPoint.extractionArea); 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; } } private static void MausoleumHideExtractionAreaVisual(GameObject? extractionArea) { if ((Object)(object)extractionArea == (Object)null) { return; } Renderer[] componentsInChildren = extractionArea.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val != (Object)null) { val.enabled = false; } } } 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 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 && val.IsValid()) { 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 && prefabRef.IsValid()).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 && startRoom.IsValid()) { 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; } Type type = stateMachine.GetType(); while (type != null) { foreach (FieldInfo declaredField in AccessTools.GetDeclaredFields(type)) { if (typeof(LevelGenerator).IsAssignableFrom(declaredField.FieldType)) { LevelGenerator value = Traverse.Create(stateMachine).Field(declaredField.Name).GetValue<LevelGenerator>(); if ((Object)(object)value != (Object)null) { return value; } } } type = type.BaseType; } return null; } internal bool MausoleumTryStartSilentLevelPoint(LevelPoint levelPoint) { if (!MausoleumIsMausoleumLevelPoint(levelPoint)) { return false; } if ((Object)(object)LevelGenerator.Instance != (Object)null) { LevelGenerator instance = LevelGenerator.Instance; if (instance.LevelPathPoints == null) { instance.LevelPathPoints = new List<LevelPoint>(); } if (!LevelGenerator.Instance.LevelPathPoints.Contains(levelPoint)) { LevelGenerator.Instance.LevelPathPoints.Add(levelPoint); } if (levelPoint.Truck) { LevelGenerator.Instance.LevelPathTruck = levelPoint; } } if ((Object)(object)((Component)levelPoint).GetComponentInParent<StartRoom>() != (Object)null) { MausoleumSetLevelPointBool(levelPoint, "inStartRoom", value: true); } ((MonoBehaviour)this).StartCoroutine(MausoleumSilentLevelPointCheck(levelPoint)); return true; } private static void MausoleumSetLevelPointBool(LevelPoint levelPoint, string fieldName, bool value) { try { if (AccessTools.Field(((object)levelPoint).GetType(), fieldName) != null) { Traverse.Create((object)levelPoint).Field(fieldName).SetValue((object)value); } } catch { } } private static bool MausoleumIsMausoleumLevelPoint(LevelPoint? levelPoint) { if ((Object)(object)levelPoint == (Object)null) { return false; } if (MausoleumIsCurrentLevel()) { return true; } Module componentInParent = ((Component)levelPoint).GetComponentInParent<Module>(); if ((Object)(object)componentInParent != (Object)null && !string.IsNullOrWhiteSpace(((Object)componentInParent).name) && ((Object)componentInParent).name.IndexOf("mausoleum", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } StartRoom componentInParent2 = ((Component)levelPoint).GetComponentInParent<StartRoom>(); if ((Object)(object)componentInParent2 != (Object)null && !string.IsNullOrWhiteSpace(((Object)componentInParent2).name) && ((Object)componentInParent2).name.IndexOf("mausoleum", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } Transform val = ((Component)levelPoint).transform; while ((Object)(object)val != (Object)null) { if (!string.IsNullOrWhiteSpace(((Object)val).name) && ((Object)val).name.IndexOf("mausoleum", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } val = val.parent; } return false; } 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) { yield break; } 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); if (levelPoint.ModuleConnect) { MausoleumSetLevelPointBool(levelPoint, "ModuleConnected", value: true); } } } 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(LevelPoint), "Start")] internal static class MausoleumCompatPatchLevelPointStartPatch { [HarmonyPrefix] private static bool MausoleumPrefix(LevelPoint __instance) { MausoleumCompatPatchPlugin instance = MausoleumCompatPatchPlugin.Instance; if ((Object)(object)instance == (Object)null || !instance.MausoleumTryStartSilentLevelPoint(__instance)) { return true; } return false; } } [HarmonyPatch(typeof(LoadingUI), "LevelAnimationStart")] internal static class MausoleumCompatPatchLoadingUILevelAnimationStartPatch { [HarmonyPostfix] private static void MausoleumPostfix(LoadingUI __instance) { MausoleumCompatPatchPlugin.MausoleumApplyLoadingGraphics(__instance); } } [HarmonyPatch(typeof(LevelGenerator), "StartRoomGeneration")] internal static class MausoleumCompatPatchStartRoomGenerationPatch { [HarmonyPrefix] private static void MausoleumPrefix() { if (MausoleumCompatPatchPlugin.MausoleumIsCurrentLevel()) { MausoleumCompatPatchPlugin.Instance?.MausoleumTryRepairCurrentLevel(); } } } [HarmonyPatch(typeof(StartRoom), "Start")] internal static class MausoleumCompatPatchStartRoomStartPatch { [HarmonyPostfix] private static void MausoleumPostfix(StartRoom __instance) { MausoleumCompatPatchPlugin.MausoleumActivateVehicleChargingStation(__instance); } } [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; } } [HarmonyPatch] internal static class MausoleumCompatPatchUnityLogPatch { private static IEnumerable<MethodBase> TargetMethods() { Type type = AccessTools.TypeByName("UnityEngine.DebugLogHandler"); if (!(type == null)) { return from method in AccessTools.GetDeclaredMethods(type) where method.Name == "LogFormat" select method; } return Enumerable.Empty<MethodBase>(); } [HarmonyPrefix] private static bool MausoleumPrefix(LogType logType, string format, object[] args) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) return !MausoleumCompatPatchPlugin.MausoleumShouldSuppressUnityLog(logType, format, args); } } }