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