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 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 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.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 MausoleumLoadingSprites = new List(); 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 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 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)) { AssetBundle val = MausoleumGetBundle(); if ((Object)(object)val != (Object)null) { MausoleumEnsureLevelLoadingGraphics(level, val); } _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)) { 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? 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 (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(); 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(); 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, 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(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(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((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(); 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 { 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(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(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)prefab.GetComponentsInChildren(true)).FirstOrDefault((Func)((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(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); 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(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(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().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(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)prefab.GetComponentsInChildren(true)).FirstOrDefault((Func)((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)((Component)root).GetComponentsInChildren(true)).FirstOrDefault((Func)((Transform child) => (Object)(object)child != (Object)null && string.Equals(((Object)child).name, name2, StringComparison.OrdinalIgnoreCase))); } private static T MausoleumGetComponentField(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(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(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(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() ?? gameObject.AddComponent(); 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(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 && 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(); } 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 void MausoleumEnsureLevelLoadingGraphics(Level level, AssetBundle bundle) { List 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 MausoleumCollectLoadingGraphics(AssetBundle bundle) { List list = new List(); HashSet hashSet = new HashSet(StringComparer.OrdinalIgnoreCase); List source = (from sprite in bundle.LoadAllAssets() 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)source).FirstOrDefault((Func)((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(((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 name) => name, StringComparer.OrdinalIgnoreCase)) { Sprite val2 = bundle.LoadAsset(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 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(((Object)item2).name) != (Object)null; list.Add(new MausoleumLoadingGraphic(bundle, item2, ((Object)item2).name, canUsePrefabRef2)); } } return list; } private static void MausoleumCacheLoadingSprites(IEnumerable 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()).GetValue(); } 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(); 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; } 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(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 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 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 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(); 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(); } if (!LevelGenerator.Instance.LevelPathPoints.Contains(levelPoint)) { LevelGenerator.Instance.LevelPathPoints.Add(levelPoint); } if (levelPoint.Truck) { LevelGenerator.Instance.LevelPathTruck = levelPoint; } } if ((Object)(object)((Component)levelPoint).GetComponentInParent() != (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(); 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(); 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? 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(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 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; } } [HarmonyPatch] internal static class MausoleumCompatPatchUnityLogPatch { private static IEnumerable 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(); } [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); } } }