Decompiled source of BCMERMoreExitsLadderPatch v1.0.0

BCMERMoreExitsLadderPatch.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[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("erockuli")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © 2026 erockuli")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BCMERMoreExitsLadderPatch")]
[assembly: AssemblyTitle("BCMERMoreExitsLadderPatch")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 BCMERMoreExitsLadderPatch
{
	[BepInPlugin("com.chatgpt.bcmer.moreexitsladderpatch", "BCMER More Exits Ladder Patch", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "com.chatgpt.bcmer.moreexitsladderpatch";

		public const string PluginName = "BCMER More Exits Ladder Patch";

		public const string PluginVersion = "1.0.0";

		private static Plugin _instance;

		private static Harmony _harmony;

		private static ConfigEntry<bool> _alwaysSpawnMoreExits;

		private static ConfigEntry<bool> _extendLadders;

		private static ConfigEntry<float> _maxProbeDistance;

		private static ConfigEntry<float> _ceilingProbeDistance;

		private static ConfigEntry<float> _clearanceAboveHit;

		private static ConfigEntry<bool> _extendLadderInteraction;

		private static ConfigEntry<float> _maxLadderInteractionRange;

		private static ConfigEntry<bool> _repeatLadderSections;

		private static bool _patchesInstalled;

		private static bool _warnedMoreExitsMissing;

		private static bool _warnedMoreExitsDisabled;

		private const int MaxPatchDiscoveryAttempts = 30;

		private const float PatchDiscoveryRetryIntervalSeconds = 2f;

		private static string _lastPatchDiscoveryWarning;

		private const int MaxLadderAdjustmentAttempts = 4;

		private const float FirstLadderAdjustmentDelaySeconds = 0.2f;

		private const float LadderAdjustmentRetryDelaySeconds = 0.25f;

		private const string LadderPassageTypeName = "BrutalCompanyMinus.Minus.MonoBehaviours.BunkerLadderPassage";

		private static readonly HashSet<int> ProcessedEscapeRoots = new HashSet<int>();

		private readonly Dictionary<int, Coroutine> _activeLadderAdjustments = new Dictionary<int, Coroutine>();

		private void Awake()
		{
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Expected O, but got Unknown
			_instance = this;
			_alwaysSpawnMoreExits = ((BaseUnityPlugin)this).Config.Bind<bool>("More Exits", "Always spawn More Exits", true, "Guarantee BCMER's existing MoreExits event on each eligible moon landing, even when normal event selection does not pick it. Turning this off restores BCMER's normal random chance; it does not disable the event.");
			_extendLadders = ((BaseUnityPlugin)this).Config.Bind<bool>("More Exits", "Extend exit ladders to first collision", true, "Restore 0.1.6's original downward raycast and lowest fixed upward-facing floor selection so tall custom interiors still fit all the way to the floor.");
			_maxProbeDistance = ((BaseUnityPlugin)this).Config.Bind<float>("More Exits", "Maximum downward collision probe distance", 100f, "Maximum distance in Unity metres to search downward from an exit ladder for the floor or another walkable surface.");
			_ceilingProbeDistance = ((BaseUnityPlugin)this).Config.Bind<float>("More Exits", "Maximum upward hatch placement probe distance", 40f, "Maximum distance in Unity metres BCMER searches upward from an interior AI node to find a surface for a ceiling exit hatch. Increase this for very tall rooms.");
			_clearanceAboveHit = ((BaseUnityPlugin)this).Config.Bind<float>("More Exits", "Ladder clearance above collision", 0.02f, "Leave this much space above the hit surface instead of extending the ladder into it.");
			_extendLadderInteraction = ((BaseUnityPlugin)this).Config.Bind<bool>("More Exits", "Extend ladder climb interaction down the ladder", true, "Resize the actual BunkerLadderPassage.passageTrigger collider so the hatch interaction can be targeted from the ladder bottom.");
			_maxLadderInteractionRange = ((BaseUnityPlugin)this).Config.Bind<float>("More Exits", "Maximum ladder interaction distance", 100f, "Upper limit for the ladder's interaction distance in metres. Actual distance is based on the extended ladder length, up to this limit.");
			_repeatLadderSections = ((BaseUnityPlugin)this).Config.Bind<bool>("More Exits", "Repeat ladder sections when extended", true, "Keep the original ladder mesh at its original scale and add aligned copies, so the ladder/texture repeats instead of stretching over a tall room.");
			_harmony = new Harmony("com.chatgpt.bcmer.moreexitsladderpatch");
			TryInstallPatches();
			if (!_patchesInstalled)
			{
				((MonoBehaviour)this).StartCoroutine(RetryPatchDiscovery());
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Loaded 0.1.11. Ladder adjustment is event-driven; no per-frame Update loop or scene-wide ladder polling is used.");
		}

		private IEnumerator RetryPatchDiscovery()
		{
			for (int attempt = 1; attempt <= 30; attempt++)
			{
				if (_patchesInstalled)
				{
					yield break;
				}
				yield return (object)new WaitForSecondsRealtime(2f);
				if (_patchesInstalled)
				{
					yield break;
				}
				TryInstallPatches();
			}
			if (!_patchesInstalled)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Harmony patch discovery stopped after " + 30 + " attempts. BCMER targets were still unavailable; check that BrutalCompanyMinusExtraReborn is installed and compatible, then restart the game."));
			}
		}

		private static void LogPatchDiscoveryWarningOnce(string message)
		{
			if (!((Object)(object)_instance == (Object)null) && !string.IsNullOrWhiteSpace(message) && !string.Equals(_lastPatchDiscoveryWarning, message, StringComparison.Ordinal))
			{
				_lastPatchDiscoveryWarning = message;
				((BaseUnityPlugin)_instance).Logger.LogWarning((object)message);
			}
		}

		private static void TryInstallPatches()
		{
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Expected O, but got Unknown
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Expected O, but got Unknown
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Expected O, but got Unknown
			if (_patchesInstalled || _harmony == null)
			{
				return;
			}
			try
			{
				Type type = AccessTools.TypeByName("RoundManager");
				Type type2 = AccessTools.TypeByName("BrutalCompanyMinus.Minus.EventManager");
				Type type3 = FindLoadedTypeQuietly("BrutalCompanyMinus.Minus.MonoBehaviours.Passage");
				Type type4 = FindLoadedTypeQuietly("BrutalCompanyMinus.Minus.MonoBehaviours.BunkerLadderPassage");
				if (!(type == null) && !(type2 == null) && !(type3 == null) && !(type4 == null))
				{
					MethodInfo methodInfo = AccessTools.Method(type, "LoadNewLevel", (Type[])null, (Type[])null);
					MethodInfo methodInfo2 = AccessTools.Method(type3, "OnNetworkSpawn", (Type[])null, (Type[])null);
					MethodInfo methodInfo3 = AccessTools.Method(type3, "DoSpawnBunkerPassage", (Type[])null, (Type[])null);
					if (methodInfo == null || methodInfo2 == null || methodInfo3 == null)
					{
						LogPatchDiscoveryWarningOnce("Could not find RoundManager.LoadNewLevel, BCMER Passage.OnNetworkSpawn, or Passage.DoSpawnBunkerPassage; startup discovery will retry.");
						return;
					}
					HarmonyMethod val = new HarmonyMethod(typeof(Plugin), "LoadNewLevelPrefix", (Type[])null);
					val.priority = 0;
					_harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					HarmonyMethod val2 = new HarmonyMethod(typeof(Plugin), "LadderPassageNetworkSpawnPostfix", (Type[])null);
					val2.priority = 0;
					_harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
					HarmonyMethod val3 = new HarmonyMethod(typeof(Plugin), "ExpandCeilingProbeRangeTranspiler", (Type[])null);
					_harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, (HarmonyMethod)null, val3, (HarmonyMethod)null, (HarmonyMethod)null);
					_patchesInstalled = true;
					_lastPatchDiscoveryWarning = null;
					((BaseUnityPlugin)_instance).Logger.LogInfo((object)"Installed event-driven ladder adjustment and configurable high-ceiling hatch placement. No scene-wide ladder polling or per-frame retry loop is used.");
				}
			}
			catch (Exception ex)
			{
				LogPatchDiscoveryWarningOnce("Patch installation did not finish; startup discovery will retry. " + ex.GetType().Name + ": " + ex.Message);
			}
		}

		private static IEnumerable<CodeInstruction> ExpandCeilingProbeRangeTranspiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			List<int> list2 = new List<int>();
			for (int i = 0; i < list.Count; i++)
			{
				CodeInstruction val = list[i];
				if (val.opcode == OpCodes.Ldc_R4 && val.operand is float num && Math.Abs(num - 8f) < 0.0001f)
				{
					list2.Add(i);
				}
			}
			if (list2.Count == 1)
			{
				int index = list2[0];
				list[index].opcode = OpCodes.Call;
				list[index].operand = AccessTools.Method(typeof(Plugin), "GetCeilingProbeDistance", (Type[])null, (Type[])null);
				if ((Object)(object)_instance != (Object)null)
				{
					((BaseUnityPlugin)_instance).Logger.LogInfo((object)("Expanded BCMER's unambiguous 8m upward ceiling/hatch placement probe. Configured distance: " + GetCeilingProbeDistance().ToString("0.0") + "m."));
				}
			}
			else if ((Object)(object)_instance != (Object)null)
			{
				((BaseUnityPlugin)_instance).Logger.LogWarning((object)("Safe ceiling-probe patch skipped: expected exactly one 8m literal in DoSpawnBunkerPassage, found " + list2.Count + ". Tall-room hatch placement is unchanged for this BCMER build to avoid patching the wrong constant."));
			}
			foreach (CodeInstruction item in list)
			{
				yield return item;
			}
		}

		private static float GetCeilingProbeDistance()
		{
			return Mathf.Clamp((_ceilingProbeDistance != null) ? _ceilingProbeDistance.Value : 40f, 8f, 100f);
		}

		private static void LoadNewLevelPrefix(object[] __args)
		{
			if ((Object)(object)_instance != (Object)null && _instance._activeLadderAdjustments.Count > 0)
			{
				foreach (Coroutine item in new List<Coroutine>(_instance._activeLadderAdjustments.Values))
				{
					if (item != null)
					{
						((MonoBehaviour)_instance).StopCoroutine(item);
					}
				}
				_instance._activeLadderAdjustments.Clear();
			}
			ProcessedEscapeRoots.Clear();
			if (!_alwaysSpawnMoreExits.Value || !IsServer())
			{
				return;
			}
			try
			{
				object obj = FindSelectableLevelArgument(__args) ?? GetCurrentLevelFromBCMER();
				if (obj == null)
				{
					return;
				}
				object member = GetMember(obj, "levelID");
				if ((member != null && Convert.ToInt32(member) == 3) || ReadDisableAllEvents() || IsMoonIgnored(obj))
				{
					return;
				}
				Type type = AccessTools.TypeByName("BrutalCompanyMinus.Minus.EventManager");
				if (type == null)
				{
					return;
				}
				object obj2 = FindMoreExitsEvent(type);
				if (obj2 == null)
				{
					if (!_warnedMoreExitsMissing)
					{
						_warnedMoreExitsMissing = true;
						((BaseUnityPlugin)_instance).Logger.LogWarning((object)"Could not resolve BCMER's MoreExits instance. Checked MoreExits.Instance and BCMER event lists; it was not forced.");
					}
					return;
				}
				object member2 = GetMember(obj2, "Enabled");
				if (member2 is bool && !(bool)member2)
				{
					if (!_warnedMoreExitsDisabled)
					{
						_warnedMoreExitsDisabled = true;
						((BaseUnityPlugin)_instance).Logger.LogWarning((object)"BCMER's MoreExits event is disabled in its event configuration. The patch is respecting that setting; enable MoreExits in BCMER if you want the always-spawn option to force it.");
					}
				}
				else
				{
					if (!EventAllowsCurrentMoon(type, obj2))
					{
						return;
					}
					member2 = GetMember(obj2, "Executed");
					bool flag = default(bool);
					int num;
					if (member2 is bool)
					{
						flag = (bool)member2;
						num = 1;
					}
					else
					{
						num = 0;
					}
					if (((uint)num & (flag ? 1u : 0u)) != 0)
					{
						return;
					}
					MethodInfo methodInfo = AccessTools.Method(obj2.GetType(), "Execute", (Type[])null, (Type[])null);
					if (methodInfo == null)
					{
						((BaseUnityPlugin)_instance).Logger.LogWarning((object)"BCMER's MoreExits event has no Execute method; nothing was forced.");
						return;
					}
					methodInfo.Invoke(obj2, null);
					SetMember(obj2, "Executed", true);
					SetMember(obj2, "Active", true);
					IList staticList = GetStaticList(type, "currentEvents");
					AddEventIfMissing(staticList, obj2);
					AddEventIfMissing(GetStaticList(type, "tipEventsToDo"), obj2);
					MethodInfo methodInfo2 = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "UpdateEventDescriptions" && m.GetParameters().Length == 1);
					if (methodInfo2 != null && staticList != null)
					{
						try
						{
							methodInfo2.Invoke(null, new object[1] { staticList });
						}
						catch
						{
						}
					}
					((BaseUnityPlugin)_instance).Logger.LogInfo((object)"Guaranteed BCMER MoreExits for this landing by executing the original event once. Normal event selection remains unchanged for all other events.");
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)_instance).Logger.LogError((object)("Failed to guarantee MoreExits: " + Unwrap(ex).GetType().Name + ": " + Unwrap(ex).Message));
			}
		}

		private static void LadderPassageNetworkSpawnPostfix(object __instance)
		{
			if ((Object)(object)_instance == (Object)null || _extendLadders == null || !_extendLadders.Value || __instance == null || !string.Equals(__instance.GetType().FullName, "BrutalCompanyMinus.Minus.MonoBehaviours.BunkerLadderPassage", StringComparison.Ordinal))
			{
				return;
			}
			Component val = (Component)((__instance is Component) ? __instance : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Transform val2 = FindEscapeRoot(val.transform);
			if ((Object)(object)val2 == (Object)null)
			{
				((BaseUnityPlugin)_instance).Logger.LogWarning((object)"BCMER BunkerLadderPassage spawned without a recognizable BunkerEscape parent; ladder adjustment was skipped safely.");
				return;
			}
			int instanceID = ((Object)((Component)val2).gameObject).GetInstanceID();
			if (!ProcessedEscapeRoots.Contains(instanceID) && !_instance._activeLadderAdjustments.ContainsKey(instanceID))
			{
				Coroutine value = ((MonoBehaviour)_instance).StartCoroutine(_instance.AdjustOneLadderAfterSpawn(val2, instanceID, val));
				_instance._activeLadderAdjustments[instanceID] = value;
			}
		}

		private IEnumerator AdjustOneLadderAfterSpawn(Transform escapeRoot, int rootId, Component passageComponent)
		{
			string failureReason = "the ladder did not become ready";
			try
			{
				for (int attempt = 1; attempt <= 4; attempt++)
				{
					yield return (object)new WaitForSecondsRealtime((attempt == 1) ? 0.2f : 0.25f);
					if (!_extendLadders.Value || (Object)(object)escapeRoot == (Object)null)
					{
						yield break;
					}
					if (TryExtendOneLadder(escapeRoot, passageComponent, out failureReason, out var interactionBounds, out var interactionHeight))
					{
						ProcessedEscapeRoots.Add(rootId);
						if (_extendLadderInteraction == null || !_extendLadderInteraction.Value)
						{
							yield break;
						}
						bool interactionConfigured = false;
						string interactionFailure = "the interaction setup was not attempted";
						for (int triggerAttempt = 1; triggerAttempt <= 4; triggerAttempt++)
						{
							if ((Object)(object)escapeRoot == (Object)null)
							{
								yield break;
							}
							if (ExtendLadderInteractionRange(escapeRoot, passageComponent, interactionBounds, interactionHeight, out interactionFailure))
							{
								interactionConfigured = true;
								break;
							}
							if (triggerAttempt < 4)
							{
								yield return (object)new WaitForSecondsRealtime(0.25f);
							}
						}
						if (!interactionConfigured && (Object)(object)escapeRoot != (Object)null)
						{
							((BaseUnityPlugin)_instance).Logger.LogWarning((object)("Ladder visual was adjusted, but passage interaction could not be extended after " + 4 + " targeted retries. Root: " + ((Object)escapeRoot).name + ". Reason: " + interactionFailure));
						}
						yield break;
					}
					if (failureReason.IndexOf("axis", StringComparison.OrdinalIgnoreCase) >= 0 || failureReason.IndexOf("implausible", StringComparison.OrdinalIgnoreCase) >= 0 || failureReason.IndexOf("outside the safe height range", StringComparison.OrdinalIgnoreCase) >= 0)
					{
						((BaseUnityPlugin)_instance).Logger.LogWarning((object)("Ladder left unchanged. Root: " + ((Object)escapeRoot).name + ". Reason: " + failureReason));
						ProcessedEscapeRoots.Add(rootId);
						yield break;
					}
				}
				if ((Object)(object)escapeRoot != (Object)null && !ProcessedEscapeRoots.Contains(rootId))
				{
					((BaseUnityPlugin)_instance).Logger.LogWarning((object)("Ladder left unchanged after " + 4 + " targeted attempts. Root: " + ((Object)escapeRoot).name + ". Reason: " + failureReason));
					ProcessedEscapeRoots.Add(rootId);
				}
			}
			finally
			{
				_activeLadderAdjustments.Remove(rootId);
			}
		}

		private static bool TryExtendOneLadder(Transform escapeRoot, Component passageComponent, out string failureReason, out Bounds interactionBounds, out float interactionHeight)
		{
			//IL_0008: 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_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: 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_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_0195: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			failureReason = "no failure reason supplied";
			interactionBounds = default(Bounds);
			interactionHeight = 0f;
			Transform val = FindLadderVisual(escapeRoot);
			if ((Object)(object)val == (Object)null)
			{
				failureReason = "no rendered ladder visual was found under the escape prefab";
				return false;
			}
			if (!TryGetWorldVerticalScaleAxis(val, out var axis, out var alignment))
			{
				failureReason = "none of the ladder visual's local scale axes is aligned closely enough with world vertical";
				return false;
			}
			if (!TryGetCombinedRendererBounds(val, out var bounds) || ((Bounds)(ref bounds)).size.y < 0.1f)
			{
				failureReason = "the ladder visual has no usable vertical renderer bounds";
				return false;
			}
			if (!TryFindLowestFixedFloor(escapeRoot, bounds, out var selectedHit, out var failureReason2))
			{
				failureReason = failureReason2;
				return false;
			}
			float y = ((Bounds)(ref bounds)).size.y;
			float y2 = ((Bounds)(ref bounds)).max.y;
			float num = ((RaycastHit)(ref selectedHit)).point.y + Mathf.Clamp(_clearanceAboveHit.Value, 0.01f, 0.5f);
			float num2 = (interactionHeight = y2 - num);
			if (num2 < 0.25f || num2 > Mathf.Clamp(_maxProbeDistance.Value, 5f, 150f))
			{
				failureReason = "the measured distance to the detected floor surface was outside the safe height range";
				return false;
			}
			float num3 = num2 / y;
			if (num3 < 0.05f || num3 > 80f)
			{
				failureReason = "the measured ladder scale ratio was implausible";
				return false;
			}
			int sectionCount = 1;
			bool flag = _repeatLadderSections != null && _repeatLadderSections.Value && num2 > y * 1.5f;
			if (flag && !RepeatLadderMeshSections(val, bounds, axis, num2, y2, out sectionCount))
			{
				((BaseUnityPlugin)_instance).Logger.LogWarning((object)("Could not repeat ladder visuals for '" + ((Object)val).name + "'; falling back to a single fitted mesh."));
				flag = false;
			}
			if (!flag)
			{
				Vector3 localScale = val.localScale;
				Vector3 position = val.position;
				val.localScale = SetVectorComponent(localScale, axis, ((Vector3)(ref localScale))[axis] * num3);
				if (!TryGetCombinedRendererBounds(val, out var bounds2))
				{
					val.localScale = localScale;
					val.position = position;
					failureReason = "the ladder renderer bounds became unavailable while fitting a single mesh";
					return false;
				}
				val.position += Vector3.up * (y2 - ((Bounds)(ref bounds2)).max.y);
				if (!TryGetCombinedRendererBounds(val, out bounds2) || Math.Abs(((Bounds)(ref bounds2)).size.y - num2) > 0.25f)
				{
					val.localScale = localScale;
					val.position = position;
					failureReason = "the single ladder could not be fitted accurately for this ceiling height";
					return false;
				}
			}
			float num4 = y2;
			interactionBounds = new Bounds(new Vector3(((Bounds)(ref bounds)).center.x, (num4 + num) * 0.5f, ((Bounds)(ref bounds)).center.z), new Vector3(Mathf.Max(1.5f, ((Bounds)(ref bounds)).size.x + 0.8f), num2, Mathf.Max(1.5f, ((Bounds)(ref bounds)).size.z + 0.8f)));
			if (!MovePassageSpawnToSafeLadderBottom(passageComponent, escapeRoot, ((Bounds)(ref bounds)).center, selectedHit))
			{
				((BaseUnityPlugin)_instance).Logger.LogWarning((object)"Ladder visuals reach the detected floor, but no clear nearby standing position was found; BCMER's original spawnPosition was preserved to avoid placing the player inside geometry.");
			}
			((BaseUnityPlugin)_instance).Logger.LogInfo((object)("Adjusted BCMER exit ladder '" + ((Object)val).name + "' from " + y.ToString("0.00") + "m to " + num2.ToString("0.00") + "m using " + (flag ? (sectionCount + " original-size mesh sections") : "one fitted mesh") + "; local axis " + "XYZ"[axis] + " alignment " + alignment.ToString("0.00") + "; target bottom Y=" + num.ToString("0.00") + " near '" + ((Object)((RaycastHit)(ref selectedHit)).collider).name + "'."));
			return true;
		}

		private static bool TryFindLowestFixedFloor(Transform escapeRoot, Bounds ladderBounds, out RaycastHit selectedHit, out string failureReason)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			selectedHit = default(RaycastHit);
			failureReason = "no non-trigger collision surface was found within the configured downward probe distance";
			RaycastHit[] array = Physics.RaycastAll(new Vector3(((Bounds)(ref ladderBounds)).center.x, ((Bounds)(ref ladderBounds)).max.y - 0.06f, ((Bounds)(ref ladderBounds)).center.z), Vector3.down, Mathf.Clamp(_maxProbeDistance.Value, 5f, 150f), -5, (QueryTriggerInteraction)1);
			RaycastHit? val = null;
			RaycastHit[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				RaycastHit value = array2[i];
				Collider collider = ((RaycastHit)(ref value)).collider;
				if ((Object)(object)collider == (Object)null || !collider.enabled || collider.isTrigger || ((RaycastHit)(ref value)).distance < 0.08f || (Object)(object)collider.attachedRigidbody != (Object)null)
				{
					continue;
				}
				Vector3 normal = ((RaycastHit)(ref value)).normal;
				if (Vector3.Dot(((Vector3)(ref normal)).normalized, Vector3.up) < 0.45f)
				{
					continue;
				}
				Transform transform = ((Component)collider).transform;
				if ((Object)(object)transform == (Object)(object)escapeRoot || transform.IsChildOf(escapeRoot))
				{
					continue;
				}
				switch (((Component)collider).gameObject.tag)
				{
				case "Player":
				case "Enemy":
				case "Ragdoll":
					continue;
				}
				if (val.HasValue)
				{
					float y = ((RaycastHit)(ref value)).point.y;
					RaycastHit value2 = val.Value;
					if (!(y < ((RaycastHit)(ref value2)).point.y))
					{
						continue;
					}
				}
				val = value;
			}
			if (!val.HasValue)
			{
				return false;
			}
			selectedHit = val.Value;
			failureReason = string.Empty;
			return true;
		}

		private static bool IsUsableFloorHit(Transform escapeRoot, RaycastHit hit)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			Collider collider = ((RaycastHit)(ref hit)).collider;
			if ((Object)(object)collider == (Object)null || !collider.enabled || collider.isTrigger || ((RaycastHit)(ref hit)).distance < 0.08f)
			{
				return false;
			}
			if ((Object)(object)collider.attachedRigidbody != (Object)null)
			{
				return false;
			}
			Vector3 normal = ((RaycastHit)(ref hit)).normal;
			if (Vector3.Dot(((Vector3)(ref normal)).normalized, Vector3.up) < 0.7f)
			{
				return false;
			}
			Transform transform = ((Component)collider).transform;
			if ((Object)(object)transform == (Object)(object)escapeRoot || transform.IsChildOf(escapeRoot))
			{
				return false;
			}
			switch (((Component)collider).gameObject.tag)
			{
			case "Player":
			case "Enemy":
			case "Ragdoll":
			case "InteractTrigger":
				return false;
			default:
				if (float.IsNaN(((RaycastHit)(ref hit)).point.y) || float.IsInfinity(((RaycastHit)(ref hit)).point.y))
				{
					return false;
				}
				return true;
			}
		}

		private static bool TrySampleNavMeshPosition(Vector3 point, out Vector3 navPosition, out bool apiAvailable)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			navPosition = Vector3.zero;
			apiAvailable = false;
			try
			{
				Type type = FindLoadedTypeQuietly("UnityEngine.AI.NavMesh");
				if (type == null)
				{
					return false;
				}
				MethodInfo methodInfo = type.GetMethods(BindingFlags.Static | BindingFlags.Public).FirstOrDefault(delegate(MethodInfo m)
				{
					if (m.Name != "SamplePosition")
					{
						return false;
					}
					ParameterInfo[] parameters = m.GetParameters();
					return parameters.Length == 4 && parameters[0].ParameterType == typeof(Vector3) && parameters[1].ParameterType.IsByRef && parameters[1].ParameterType.GetElementType() != null && parameters[1].ParameterType.GetElementType().FullName == "UnityEngine.AI.NavMeshHit" && parameters[2].ParameterType == typeof(float) && parameters[3].ParameterType == typeof(int);
				});
				if (methodInfo == null)
				{
					return false;
				}
				apiAvailable = true;
				object obj = Activator.CreateInstance(methodInfo.GetParameters()[1].ParameterType.GetElementType());
				object[] array = new object[4] { point, obj, 0.75f, -1 };
				object obj2 = methodInfo.Invoke(null, array);
				if (!(obj2 is bool) || !(bool)obj2)
				{
					return false;
				}
				if (!(GetMember(array[1], "position") is Vector3 val))
				{
					return false;
				}
				navPosition = val;
				return true;
			}
			catch
			{
				apiAvailable = false;
				return false;
			}
		}

		private static Vector3 SetVectorComponent(Vector3 value, int axis, float component)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			((Vector3)(ref value))[axis] = component;
			return value;
		}

		private static bool RepeatLadderMeshSections(Transform ladder, Bounds originalBounds, int scaleAxis, float targetHeight, float originalTop, out int sectionCount)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: 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_0074: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_020c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			sectionCount = 1;
			if ((Object)(object)ladder == (Object)null || (Object)(object)ladder.parent == (Object)null || ((Bounds)(ref originalBounds)).size.y < 0.1f || targetHeight <= ((Bounds)(ref originalBounds)).size.y)
			{
				return false;
			}
			float y = ((Bounds)(ref originalBounds)).size.y;
			int num = Mathf.FloorToInt(targetHeight / y);
			float num2 = targetHeight - (float)num * y;
			if (num < 1 || num > 64)
			{
				return false;
			}
			Vector3 position = ladder.position;
			Quaternion rotation = ladder.rotation;
			Vector3 localScale = ladder.localScale;
			Transform parent = ladder.parent;
			int num3 = 0;
			List<GameObject> list = new List<GameObject>();
			try
			{
				for (int i = 1; i < num; i++)
				{
					GameObject val = Object.Instantiate<GameObject>(((Component)ladder).gameObject, parent, true);
					((Object)val).name = ((Object)ladder).name + "_RepeatedSection_" + i;
					list.Add(val);
					val.transform.SetPositionAndRotation(position, rotation);
					val.transform.localScale = localScale;
					if (!TryGetCombinedRendererBounds(val.transform, out var bounds))
					{
						throw new InvalidOperationException("A repeated ladder section had no renderer bounds.");
					}
					Transform transform = val.transform;
					transform.position += Vector3.up * (originalTop - y * (float)i - ((Bounds)(ref bounds)).max.y);
					RemovePhysicsFromRepeatedVisual(val);
					num3++;
				}
				if (num2 > 0.06f)
				{
					GameObject val2 = Object.Instantiate<GameObject>(((Component)ladder).gameObject, parent, true);
					((Object)val2).name = ((Object)ladder).name + "_RepeatedSection_Partial";
					list.Add(val2);
					val2.transform.SetPositionAndRotation(position, rotation);
					Vector3 localScale2 = localScale;
					((Vector3)(ref localScale2))[scaleAxis] = ((Vector3)(ref localScale2))[scaleAxis] * Mathf.Clamp(num2 / y, 0.02f, 1f);
					val2.transform.localScale = localScale2;
					if (!TryGetCombinedRendererBounds(val2.transform, out var bounds2))
					{
						throw new InvalidOperationException("The partial ladder section had no renderer bounds.");
					}
					float num4 = originalTop - y * (float)num;
					Transform transform2 = val2.transform;
					transform2.position += Vector3.up * (num4 - ((Bounds)(ref bounds2)).max.y);
					RemovePhysicsFromRepeatedVisual(val2);
					num3++;
				}
				sectionCount = num + ((num2 > 0.06f) ? 1 : 0);
				((BaseUnityPlugin)_instance).Logger.LogInfo((object)("Repeated original ladder mesh instead of stretching it: base section " + y.ToString("0.00") + "m; required span " + targetHeight.ToString("0.00") + "m; created " + num3 + " copies; total visual sections " + sectionCount + ". Texture UVs/readability are not required."));
				return true;
			}
			catch (Exception ex)
			{
				foreach (GameObject item in list)
				{
					if ((Object)(object)item != (Object)null)
					{
						Object.Destroy((Object)(object)item);
					}
				}
				((BaseUnityPlugin)_instance).Logger.LogWarning((object)("Could not repeat ladder mesh sections; cleaned up partial copies: " + ex.GetType().Name + ": " + ex.Message));
				return false;
			}
		}

		private static void RemovePhysicsFromRepeatedVisual(GameObject repeatedVisual)
		{
			if ((Object)(object)repeatedVisual == (Object)null)
			{
				return;
			}
			Component[] componentsInChildren = repeatedVisual.GetComponentsInChildren<Component>(true);
			foreach (Component val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !(val is Transform) && !(val is MeshFilter) && !(val is Renderer) && !(val is LODGroup))
				{
					Collider val2 = (Collider)(object)((val is Collider) ? val : null);
					if ((Object)(object)val2 != (Object)null)
					{
						val2.enabled = false;
					}
					Behaviour val3 = (Behaviour)(object)((val is Behaviour) ? val : null);
					if ((Object)(object)val3 != (Object)null)
					{
						val3.enabled = false;
					}
					Rigidbody val4 = (Rigidbody)(object)((val is Rigidbody) ? val : null);
					if ((Object)(object)val4 != (Object)null)
					{
						val4.isKinematic = true;
						val4.detectCollisions = false;
					}
					Object.Destroy((Object)(object)val);
				}
			}
		}

		private static bool MovePassageSpawnToSafeLadderBottom(Component passageComponent, Transform escapeRoot, Vector3 ladderCenter, RaycastHit floorHit)
		{
			//IL_0050: 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)
			//IL_0072: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)passageComponent == (Object)null)
			{
				((BaseUnityPlugin)_instance).Logger.LogWarning((object)"Could not adjust the interior destination: BunkerLadderPassage component was unavailable.");
				return false;
			}
			object instanceMemberFromHierarchy = GetInstanceMemberFromHierarchy(passageComponent, "spawnPosition");
			Transform val = (Transform)((instanceMemberFromHierarchy is Transform) ? instanceMemberFromHierarchy : null);
			if ((Object)(object)val == (Object)null)
			{
				((BaseUnityPlugin)_instance).Logger.LogWarning((object)"BunkerLadderPassage.spawnPosition was null; the interior destination was left unchanged.");
				return false;
			}
			if (!TryFindSafeLadderDestination(escapeRoot, ladderCenter, floorHit, out var safePosition))
			{
				((BaseUnityPlugin)_instance).Logger.LogWarning((object)"Could not find a capsule-clear standing point beside the ladder on the detected floor. The serialized destination was left unchanged.");
				return false;
			}
			Vector3 position = val.position;
			val.position = safePosition;
			((BaseUnityPlugin)_instance).Logger.LogInfo((object)("Moved BunkerLadderPassage destination to a clear standing point beside the ladder bottom at (" + safePosition.x.ToString("0.00") + ", " + safePosition.y.ToString("0.00") + ", " + safePosition.z.ToString("0.00") + "); floor hit '" + (((Object)(object)((RaycastHit)(ref floorHit)).collider != (Object)null) ? ((Object)((RaycastHit)(ref floorHit)).collider).name : "unknown") + "', prior marker (" + position.x.ToString("0.00") + ", " + position.y.ToString("0.00") + ", " + position.z.ToString("0.00") + ")."));
			return true;
		}

		private static bool TryFindSafeLadderDestination(Transform escapeRoot, Vector3 ladderCenter, RaycastHit floorHit, out Vector3 safePosition)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_0071: 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_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_024f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_0265: Unknown result type (might be due to invalid IL or missing references)
			//IL_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0272: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			safePosition = Vector3.zero;
			float y = ((RaycastHit)(ref floorHit)).point.y;
			Vector2[] array = (Vector2[])(object)new Vector2[8]
			{
				new Vector2(1f, 0f),
				new Vector2(0.7071f, 0.7071f),
				new Vector2(0f, 1f),
				new Vector2(-0.7071f, 0.7071f),
				new Vector2(-1f, 0f),
				new Vector2(-0.7071f, -0.7071f),
				new Vector2(0f, -1f),
				new Vector2(0.7071f, -0.7071f)
			};
			float[] array2 = new float[5] { 0.65f, 0.9f, 1.2f, 1.5f, 0f };
			Vector3 val2 = default(Vector3);
			foreach (float num in array2)
			{
				int num2 = ((num <= 0.001f) ? 1 : array.Length);
				for (int j = 0; j < num2; j++)
				{
					Vector2 val = ((num <= 0.001f) ? Vector2.zero : array[j]);
					((Vector3)(ref val2))..ctor(ladderCenter.x + val.x * num, y + 1.75f, ladderCenter.z + val.y * num);
					if (!TryFindFloorAtXZ(escapeRoot, val2.x, val2.z, y, out var selectedHit))
					{
						continue;
					}
					Vector3 point = ((RaycastHit)(ref selectedHit)).point;
					if (TrySampleNavMeshPosition(point + Vector3.up * 0.08f, out var navPosition, out var _))
					{
						float num3 = Vector2.Distance(new Vector2(navPosition.x, navPosition.z), new Vector2(point.x, point.z));
						if (Math.Abs(navPosition.y - ((RaycastHit)(ref selectedHit)).point.y) > 0.4f || num3 > 0.7f || !TryFindFloorAtXZ(escapeRoot, navPosition.x, navPosition.z, y, out var selectedHit2) || Math.Abs(((RaycastHit)(ref selectedHit2)).point.y - navPosition.y) > 0.45f)
						{
							continue;
						}
						((Vector3)(ref point))..ctor(navPosition.x, ((RaycastHit)(ref selectedHit2)).point.y, navPosition.z);
					}
					Vector3 val3 = point + Vector3.up * 0.15f;
					if (IsCharacterCapsuleClear(val3, escapeRoot))
					{
						safePosition = val3;
						return true;
					}
				}
			}
			return false;
		}

		private static bool TryFindFloorAtXZ(Transform escapeRoot, float x, float z, float expectedFloorY, out RaycastHit selectedHit)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: 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_0046: 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_006d: Unknown result type (might be due to invalid IL or missing references)
			selectedHit = default(RaycastHit);
			RaycastHit[] array = Physics.RaycastAll(new Vector3(x, expectedFloorY + 1.75f, z), Vector3.down, 5f, -5, (QueryTriggerInteraction)1);
			float num = float.MaxValue;
			RaycastHit[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				RaycastHit val = array2[i];
				if (IsUsableFloorHit(escapeRoot, val))
				{
					float num2 = Math.Abs(((RaycastHit)(ref val)).point.y - expectedFloorY);
					if (!(num2 > 0.45f) && !(num2 >= num))
					{
						num = num2;
						selectedHit = val;
					}
				}
			}
			return num < float.MaxValue;
		}

		private static bool IsCharacterCapsuleClear(Vector3 feetPoint, Transform escapeRoot)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: 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_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = feetPoint + Vector3.up * 0.24f;
			Vector3 val2 = feetPoint + Vector3.up * 1.48f;
			Collider[] array = Physics.OverlapCapsule(val, val2, 0.22f, -5, (QueryTriggerInteraction)2);
			foreach (Collider val3 in array)
			{
				if ((Object)(object)val3 == (Object)null || !val3.enabled)
				{
					continue;
				}
				if (val3.isTrigger)
				{
					if (IsPotentiallyLethalTrigger(val3))
					{
						return false;
					}
				}
				else
				{
					switch (((Component)val3).gameObject.tag)
					{
					case "Player":
					case "Enemy":
					case "Ragdoll":
					case "InteractTrigger":
						continue;
					}
					return false;
				}
			}
			return true;
		}

		private static bool IsPotentiallyLethalTrigger(Collider collider)
		{
			if ((Object)(object)collider == (Object)null)
			{
				return false;
			}
			Transform val = ((Component)collider).transform;
			while ((Object)(object)val != (Object)null)
			{
				string text = ((Object)val).name ?? string.Empty;
				if (text.IndexOf("kill", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("death", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("damage", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("void", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("hazard", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("lethal", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static object GetInstanceMemberFromHierarchy(object target, string memberName)
		{
			if (target == null || string.IsNullOrEmpty(memberName))
			{
				return null;
			}
			Type type = target.GetType();
			while (type != null)
			{
				BindingFlags bindingAttr = BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
				FieldInfo field = type.GetField(memberName, bindingAttr);
				if (field != null)
				{
					return field.GetValue(target);
				}
				PropertyInfo property = type.GetProperty(memberName, bindingAttr);
				if (property != null && property.CanRead)
				{
					return property.GetValue(target, null);
				}
				type = type.BaseType;
			}
			return null;
		}

		private static bool ExtendLadderInteractionRange(Transform escapeRoot, Component passageComponent, Bounds ladderBounds, float targetHeight, out string failureReason)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_024b: Unknown result type (might be due to invalid IL or missing references)
			failureReason = string.Empty;
			Type type = FindLoadedTypeQuietly("InteractTrigger");
			if (type == null)
			{
				failureReason = "could not resolve the game's InteractTrigger type";
				return false;
			}
			object instanceMemberFromHierarchy = GetInstanceMemberFromHierarchy(passageComponent, "passageTrigger");
			Component val = (Component)((instanceMemberFromHierarchy is Component) ? instanceMemberFromHierarchy : null);
			bool flag = (Object)(object)val != (Object)null && type.IsAssignableFrom(((object)val).GetType());
			if (!flag)
			{
				val = null;
			}
			if ((Object)(object)val == (Object)null && (Object)(object)escapeRoot != (Object)null)
			{
				try
				{
					Component[] array = (from c in ((Component)escapeRoot).GetComponentsInChildren(type, true).OfType<Component>()
						where (Object)(object)c != (Object)null
						select c).ToArray();
					Component[] array2 = array.Where((Component c) => IsLadderTriggerObject(((Object)c.gameObject).name)).ToArray();
					Component[] array3 = ((array2.Length != 0) ? array2 : array);
					if (array2.Length != 0 || array3.Length == 1)
					{
						val = array3.OrderBy((Component c) => Vector3.SqrMagnitude(c.transform.position - new Vector3(((Bounds)(ref ladderBounds)).center.x, ((Bounds)(ref ladderBounds)).max.y, ((Bounds)(ref ladderBounds)).center.z))).FirstOrDefault();
					}
				}
				catch (Exception ex)
				{
					failureReason = "could not inspect escape-prefab InteractTrigger components: " + ex.GetType().Name;
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				int num = ((!((Object)(object)escapeRoot == (Object)null)) ? ((Component)escapeRoot).GetComponentsInChildren(type, true).Length : 0);
				if (string.IsNullOrEmpty(failureReason))
				{
					failureReason = ((num > 1) ? "multiple InteractTrigger components were ambiguous; refused to resize the wrong one" : ("no InteractTrigger was available on BunkerLadderPassage.passageTrigger or inside the escape prefab (found " + num + ")"));
				}
				return false;
			}
			try
			{
				Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null);
				if (!val.gameObject.activeInHierarchy || ((Object)(object)val2 != (Object)null && !val2.enabled))
				{
					failureReason = "passage interaction trigger '" + ((Object)val.gameObject).name + "' is inactive/disabled; its state was left unchanged";
					return false;
				}
				EnsureRaycastableInteractTrigger(val);
				float num2 = Mathf.Clamp((_maxLadderInteractionRange != null) ? _maxLadderInteractionRange.Value : 100f, 2f, 150f);
				float desiredRange = Mathf.Min(targetHeight + 2f, num2);
				bool flag2 = RaiseInteractionRadius(val, desiredRange);
				BoxCollider val3 = val.GetComponent<BoxCollider>();
				bool flag3 = (Object)(object)val3 == (Object)null;
				if ((Object)(object)val3 == (Object)null)
				{
					val3 = val.gameObject.AddComponent<BoxCollider>();
				}
				if (!ConfigureBoxColliderToWorldBounds(val3, val.transform, ladderBounds))
				{
					if (flag3 && (Object)(object)val3 != (Object)null)
					{
						Object.Destroy((Object)(object)val3);
					}
					failureReason = "could not configure the passage BoxCollider to cover the floor-to-hatch span";
					return false;
				}
				((Collider)val3).isTrigger = true;
				((Collider)val3).enabled = true;
				((BaseUnityPlugin)_instance).Logger.LogInfo((object)("Extended actual passage interaction trigger '" + ((Object)val.gameObject).name + "'" + (flag ? " via BunkerLadderPassage.passageTrigger" : " via escape-hierarchy fallback") + ": active=" + val.gameObject.activeInHierarchy + ", componentEnabled=" + ((Object)(object)val2 == (Object)null || val2.enabled) + ", layer=" + LayerMask.LayerToName(val.gameObject.layer) + ", boxCollider=covers floor-to-hatch span" + (flag3 ? " (new box)" : "") + ", optional interactRadiusField=" + (flag2 ? ("available; desired cap " + desiredRange.ToString("0.0") + "m") : "unavailable; expanded collider handles targeting") + "."));
				return true;
			}
			catch (Exception ex2)
			{
				failureReason = "failed to extend the actual passage interaction trigger: " + ex2.GetType().Name + ": " + ex2.Message;
				return false;
			}
		}

		private static bool IsLadderTriggerObject(string name)
		{
			if (!string.IsNullOrEmpty(name))
			{
				if (name.IndexOf("LadderTrigger", StringComparison.OrdinalIgnoreCase) < 0 && name.IndexOf("EscapePassage", StringComparison.OrdinalIgnoreCase) < 0)
				{
					return string.Equals(name, "EscapeLadder", StringComparison.OrdinalIgnoreCase);
				}
				return true;
			}
			return false;
		}

		private static void EnsureRaycastableInteractTrigger(Component trigger)
		{
			if ((Object)(object)trigger == (Object)null)
			{
				return;
			}
			int num = LayerMask.NameToLayer("InteractableObject");
			if (num < 0)
			{
				num = LayerMask.NameToLayer("Interactable");
			}
			if (num >= 0 && trigger.gameObject.layer != num)
			{
				trigger.gameObject.layer = num;
			}
			try
			{
				if (!string.Equals(trigger.gameObject.tag, "InteractTrigger", StringComparison.Ordinal))
				{
					trigger.gameObject.tag = "InteractTrigger";
				}
			}
			catch
			{
			}
		}

		private static bool ConfigureBoxColliderToWorldBounds(BoxCollider box, Transform target, Bounds worldBounds)
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: 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_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: 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_004a: 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_0056: 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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: 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)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: 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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_015b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: 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)
			//IL_0165: 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)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01df: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)box == (Object)null || (Object)(object)target == (Object)null)
			{
				return false;
			}
			Vector3 min = ((Bounds)(ref worldBounds)).min;
			Vector3 max = ((Bounds)(ref worldBounds)).max;
			Vector3[] obj = new Vector3[8]
			{
				new Vector3(min.x, min.y, min.z),
				new Vector3(min.x, min.y, max.z),
				new Vector3(min.x, max.y, min.z),
				new Vector3(min.x, max.y, max.z),
				new Vector3(max.x, min.y, min.z),
				new Vector3(max.x, min.y, max.z),
				new Vector3(max.x, max.y, min.z),
				new Vector3(max.x, max.y, max.z)
			};
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(float.PositiveInfinity, float.PositiveInfinity, float.PositiveInfinity);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(float.NegativeInfinity, float.NegativeInfinity, float.NegativeInfinity);
			Vector3[] array = (Vector3[])(object)obj;
			foreach (Vector3 val3 in array)
			{
				Vector3 val4 = target.InverseTransformPoint(val3);
				val = Vector3.Min(val, val4);
				val2 = Vector3.Max(val2, val4);
			}
			box.center = (val + val2) * 0.5f;
			box.size = new Vector3(Mathf.Max(0.6f, val2.x - val.x), Mathf.Max(0.6f, val2.y - val.y), Mathf.Max(0.6f, val2.z - val.z));
			((Collider)box).isTrigger = true;
			((Collider)box).enabled = true;
			return true;
		}

		private static bool RaiseInteractionRadius(Component interactTrigger, float desiredRange)
		{
			if ((Object)(object)interactTrigger == (Object)null)
			{
				return false;
			}
			string[] array = new string[1] { "interactRadius" };
			try
			{
				Type type = ((object)interactTrigger).GetType();
				while (type != null)
				{
					string[] array2 = array;
					foreach (string name in array2)
					{
						FieldInfo field = type.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (field != null && (field.FieldType == typeof(float) || field.FieldType == typeof(double)) && !field.IsInitOnly)
						{
							if (Convert.ToSingle(field.GetValue(interactTrigger)) < desiredRange)
							{
								field.SetValue(interactTrigger, (field.FieldType == typeof(double)) ? ((object)(double)desiredRange) : ((object)desiredRange));
							}
							return true;
						}
						PropertyInfo property = type.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
						if (property != null && property.CanRead && property.CanWrite && (property.PropertyType == typeof(float) || property.PropertyType == typeof(double)))
						{
							if (Convert.ToSingle(property.GetValue(interactTrigger, null)) < desiredRange)
							{
								property.SetValue(interactTrigger, (property.PropertyType == typeof(double)) ? ((object)(double)desiredRange) : ((object)desiredRange), null);
							}
							return true;
						}
					}
					type = type.BaseType;
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)_instance).Logger.LogWarning((object)("Could not update an optional passage interaction-distance member: " + ex.GetType().Name));
			}
			return false;
		}

		private static bool TryGetWorldVerticalScaleAxis(Transform target, out int axis, out float alignment)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//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_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: 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)
			//IL_0067: 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)
			Vector3[] array = new Vector3[3];
			Vector3 val = target.right;
			array[0] = ((Vector3)(ref val)).normalized;
			val = target.up;
			array[1] = ((Vector3)(ref val)).normalized;
			val = target.forward;
			array[2] = ((Vector3)(ref val)).normalized;
			Vector3[] array2 = (Vector3[])(object)array;
			axis = 0;
			alignment = Mathf.Abs(Vector3.Dot(array2[0], Vector3.up));
			for (int i = 1; i < array2.Length; i++)
			{
				float num = Mathf.Abs(Vector3.Dot(array2[i], Vector3.up));
				if (num > alignment)
				{
					axis = i;
					alignment = num;
				}
			}
			return alignment >= 0.55f;
		}

		private static Transform FindEscapeRoot(Transform passage)
		{
			Transform val = passage;
			while ((Object)(object)val != (Object)null)
			{
				if (((Object)val).name.IndexOf("BunkerEscape", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return val;
				}
				val = val.parent;
			}
			return null;
		}

		private static Transform FindLadderVisual(Transform root)
		{
			Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true);
			List<Tuple<Transform, int>> list = new List<Tuple<Transform, int>>();
			Transform[] array = componentsInChildren;
			foreach (Transform val in array)
			{
				string text = ((Object)val).name ?? string.Empty;
				if (text.IndexOf("ladder", StringComparison.OrdinalIgnoreCase) < 0 || text.IndexOf("trigger", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("RepeatedSection", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					continue;
				}
				Renderer[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<Renderer>(true);
				if (componentsInChildren2 != null && !componentsInChildren2.All((Renderer r) => (Object)(object)r == (Object)null))
				{
					int num = 0;
					Transform val2 = val;
					while ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)root)
					{
						num++;
						val2 = val2.parent;
					}
					list.Add(Tuple.Create<Transform, int>(val, num));
				}
			}
			return (from c in list
				orderby c.Item2
				select c.Item1).FirstOrDefault();
		}

		private static bool TryGetCombinedRendererBounds(Transform root, out Bounds bounds)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: 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)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			bounds = new Bounds(root.position, Vector3.zero);
			bool flag = false;
			Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>(true);
			if (componentsInChildren == null)
			{
				return false;
			}
			Renderer[] array = componentsInChildren;
			foreach (Renderer val in array)
			{
				if (!((Object)(object)val == (Object)null))
				{
					if (!flag)
					{
						bounds = val.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref bounds)).Encapsulate(val.bounds);
					}
				}
			}
			return flag;
		}

		private static object FindSelectableLevelArgument(object[] args)
		{
			if (args == null)
			{
				return null;
			}
			foreach (object obj in args)
			{
				if (obj != null && obj.GetType().Name == "SelectableLevel")
				{
					return obj;
				}
			}
			return null;
		}

		private static object GetCurrentLevelFromBCMER()
		{
			Type type = AccessTools.TypeByName("BrutalCompanyMinus.Minus.Manager");
			if (!(type != null))
			{
				return null;
			}
			return GetStaticMember(type, "currentLevel");
		}

		private static object FindMoreExitsEvent(Type eventManagerType)
		{
			object staticMember = GetStaticMember(FindLoadedTypeQuietly("BrutalCompanyMinus.Minus.Events.MoreExits"), "Instance");
			if (staticMember != null)
			{
				return staticMember;
			}
			string[] array = new string[4] { "events", "disabledEvents", "vanillaEvents", "moddedEvents" };
			foreach (string fieldName in array)
			{
				IList staticList = GetStaticList(eventManagerType, fieldName);
				if (staticList == null)
				{
					continue;
				}
				foreach (object item in staticList)
				{
					if (string.Equals(InvokeName(item), "MoreExits", StringComparison.OrdinalIgnoreCase))
					{
						return item;
					}
				}
			}
			return null;
		}

		private static object FindEvent(Type eventManagerType, string wantedName)
		{
			IList staticList = GetStaticList(eventManagerType, "events");
			if (staticList == null)
			{
				return null;
			}
			foreach (object item in staticList)
			{
				if (item != null && string.Equals(InvokeName(item), wantedName, StringComparison.OrdinalIgnoreCase))
				{
					return item;
				}
			}
			return null;
		}

		private static Type FindLoadedTypeQuietly(string fullName)
		{
			if (string.IsNullOrWhiteSpace(fullName))
			{
				return null;
			}
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly in assemblies)
			{
				try
				{
					Type type = assembly.GetType(fullName, throwOnError: false);
					if (type != null)
					{
						return type;
					}
				}
				catch
				{
				}
			}
			return null;
		}

		private static bool EventAllowsCurrentMoon(Type eventManagerType, object eventObject)
		{
			object member = GetMember(eventObject, "MoonMode");
			bool flag = default(bool);
			int num;
			if (member is bool)
			{
				flag = (bool)member;
				num = 1;
			}
			else
			{
				num = 0;
			}
			bool flag2 = (byte)((uint)num & (flag ? 1u : 0u)) != 0;
			string checkerName = (flag2 ? "IsEventOnMoonWhitelist" : "IsIgnoredEventByMoonBlacklist");
			MethodInfo methodInfo = eventManagerType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == checkerName && m.GetParameters().Length == 1);
			if (methodInfo == null)
			{
				return true;
			}
			try
			{
				bool flag3 = Convert.ToBoolean(methodInfo.Invoke(null, new object[1] { eventObject }));
				return flag2 ? flag3 : (!flag3);
			}
			catch
			{
				return true;
			}
		}

		private static bool IsMoonIgnored(object level)
		{
			Type type = AccessTools.TypeByName("BrutalCompanyMinus.Minus.EventManager");
			if (type == null)
			{
				return false;
			}
			MethodInfo methodInfo = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).FirstOrDefault((MethodInfo m) => m.Name == "IsIgnoredMoon" && m.GetParameters().Length == 1 && m.GetParameters()[0].ParameterType == typeof(string));
			if (methodInfo == null)
			{
				return false;
			}
			string text = Convert.ToString(GetMember(level, "PlanetName"));
			string text2 = Convert.ToString(GetMember(level, "name"));
			try
			{
				if (!string.IsNullOrWhiteSpace(text) && Convert.ToBoolean(methodInfo.Invoke(null, new object[1] { text })))
				{
					return true;
				}
				if (!string.IsNullOrWhiteSpace(text2) && Convert.ToBoolean(methodInfo.Invoke(null, new object[1] { text2 })))
				{
					return true;
				}
			}
			catch
			{
			}
			return false;
		}

		private static bool ReadDisableAllEvents()
		{
			Type type = FindLoadedTypeQuietly("BrutalCompanyMinus.Configuration");
			if (type == null)
			{
				return false;
			}
			object member = GetMember(GetStaticMember(type, "DisableAllEvents"), "Value");
			bool flag = default(bool);
			int num;
			if (member is bool)
			{
				flag = (bool)member;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		private static bool IsServer()
		{
			Type type = AccessTools.TypeByName("Unity.Netcode.NetworkManager");
			if (type == null)
			{
				return false;
			}
			object member = GetMember(GetStaticMember(type, "Singleton"), "IsServer");
			bool flag = default(bool);
			int num;
			if (member is bool)
			{
				flag = (bool)member;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		private static IList GetStaticList(Type type, string fieldName)
		{
			return GetStaticMember(type, fieldName) as IList;
		}

		private static void AddEventIfMissing(IList list, object eventObject)
		{
			if (list == null || eventObject == null)
			{
				return;
			}
			string b = InvokeName(eventObject);
			foreach (object item in list)
			{
				if (item == eventObject || string.Equals(InvokeName(item), b, StringComparison.OrdinalIgnoreCase))
				{
					return;
				}
			}
			list.Add(eventObject);
		}

		private static string InvokeName(object eventObject)
		{
			if (eventObject == null)
			{
				return string.Empty;
			}
			try
			{
				MethodInfo methodInfo = AccessTools.Method(eventObject.GetType(), "Name", (Type[])null, (Type[])null);
				return (methodInfo != null) ? Convert.ToString(methodInfo.Invoke(eventObject, null)) : string.Empty;
			}
			catch
			{
				return string.Empty;
			}
		}

		private static object GetStaticMember(Type type, string name)
		{
			if (type == null)
			{
				return null;
			}
			BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;
			FieldInfo field = type.GetField(name, bindingAttr);
			if (field != null)
			{
				return field.GetValue(null);
			}
			PropertyInfo property = type.GetProperty(name, bindingAttr);
			if (!(property != null))
			{
				return null;
			}
			return property.GetValue(null, null);
		}

		private static object GetMember(object target, string name)
		{
			if (target == null || string.IsNullOrEmpty(name))
			{
				return null;
			}
			Type type = target.GetType();
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			FieldInfo field = type.GetField(name, bindingAttr);
			if (field != null)
			{
				return field.GetValue(target);
			}
			PropertyInfo property = type.GetProperty(name, bindingAttr);
			if (!(property != null))
			{
				return null;
			}
			return property.GetValue(target, null);
		}

		private static bool SetMember(object target, string name, object value)
		{
			if (target == null)
			{
				return false;
			}
			Type type = target.GetType();
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			FieldInfo field = type.GetField(name, bindingAttr);
			if (field != null)
			{
				field.SetValue(target, value);
				return true;
			}
			PropertyInfo property = type.GetProperty(name, bindingAttr);
			if (property != null && property.CanWrite)
			{
				property.SetValue(target, value, null);
				return true;
			}
			return false;
		}

		private static Exception Unwrap(Exception ex)
		{
			if (!(ex is TargetInvocationException { InnerException: not null } ex2))
			{
				return ex;
			}
			return ex2.InnerException;
		}
	}
}