Decompiled source of Echohold Fix Plus v1.0.0

EchoholdFixPlus.dll

Decompiled 20 hours ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using TMPro;
using UnityEngine;
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: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("Midorino")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+b24e3fcb591b98a2e17e6d618a7603905068ceed")]
[assembly: AssemblyProduct("EchoholdFixPlus")]
[assembly: AssemblyTitle("EchoholdFixPlus")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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]
	[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]
	[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 EchoholdFixPlus
{
	[HarmonyPatch(typeof(ItemDrone), "SphereCheck")]
	internal static class DroneFallback
	{
		[HarmonyPostfix]
		private static void Postfix(ItemDrone __instance, float _radius, ref bool __result)
		{
			if (__result || !Plugin.FixDroneTargeting.Value || (Object)(object)__instance == (Object)null || !__instance.targetValuables)
			{
				return;
			}
			try
			{
				__result = TryTargetEchoholdValuable(__instance, _radius);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("Drone fallback failed: " + ex.Message));
			}
		}

		private static bool TryTargetEchoholdValuable(ItemDrone drone, float radius)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)drone.itemBattery != (Object)null && drone.itemBattery.batteryLife <= 0f)
			{
				return false;
			}
			Vector3 position = ((Component)drone).transform.position;
			int mask = LayerMask.GetMask(new string[1] { "Default" });
			Collider val = null;
			Transform val2 = null;
			PhysGrabObjectCollider val3 = null;
			float num = float.MaxValue;
			Collider[] array = Physics.OverlapSphere(position, radius);
			foreach (Collider val4 in array)
			{
				PhysGrabObjectCollider component = ((Component)val4).GetComponent<PhysGrabObjectCollider>();
				if ((Object)(object)component == (Object)null)
				{
					continue;
				}
				Transform highestParentWithRigidbody = drone.GetHighestParentWithRigidbody(((Component)val4).transform);
				if ((Object)(object)highestParentWithRigidbody == (Object)null || (Object)(object)highestParentWithRigidbody == (Object)(object)((Component)drone).transform || !((Component)highestParentWithRigidbody).gameObject.activeSelf)
				{
					continue;
				}
				ValuableObject component2 = ((Component)highestParentWithRigidbody).GetComponent<ValuableObject>();
				PhysGrabObjectImpactDetector component3 = ((Component)highestParentWithRigidbody).GetComponent<PhysGrabObjectImpactDetector>();
				if (!((Object)(object)component2 == (Object)null) && !((Object)(object)component3 == (Object)null) && component3.isValuable && ValuableFixes.IsEchoholdValuable((Component)(object)component2) && (drone.customTargetingCondition == null || drone.customTargetingCondition.CustomTargetingCondition(((Component)highestParentWithRigidbody).gameObject)))
				{
					Vector3 val5 = val4.ClosestPoint(position);
					float num2 = Vector3.Distance(position, val5);
					if (!(num2 >= num) && !Blocked(position, val5, highestParentWithRigidbody, ((Component)drone).transform, mask))
					{
						val = val4;
						val2 = highestParentWithRigidbody;
						val3 = component;
						num = num2;
					}
				}
			}
			if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null)
			{
				return false;
			}
			drone.playerTumbleTarget = null;
			drone.playerAvatarTarget = null;
			drone.targetIsPlayer = false;
			drone.targetIsEnemy = false;
			drone.targetIsLocalPlayer = false;
			drone.magnetTarget = ((Component)val).transform;
			drone.magnetTargetPhysGrabObject = ((Component)val2).GetComponent<PhysGrabObject>();
			drone.magnetTargetRigidbody = ((Component)val2).GetComponent<Rigidbody>();
			drone.NewRayHitPoint(((Component)val).transform.position, ((Component)val2).GetComponent<PhotonView>().ViewID, val3.colliderID, val2);
			drone.attachPoint = drone.rayHitPosition;
			drone.enemyTarget = null;
			Plugin.Log.LogDebug((object)("Drone: targeted " + ValuableFixes.TypeName((Component)(object)val2) + " by the fallback check"));
			return true;
		}

		private static bool Blocked(Vector3 from, Vector3 to, Transform target, Transform drone, int mask)
		{
			//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_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_001a: 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_001d: 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_0037: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = to - from;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude < 0.01f)
			{
				return false;
			}
			RaycastHit[] array = Physics.RaycastAll(from, val / magnitude, magnitude, mask, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val2 = array[i];
				Transform transform = ((Component)((RaycastHit)(ref val2)).collider).transform;
				if (!transform.IsChildOf(target) && !transform.IsChildOf(drone))
				{
					return true;
				}
			}
			return false;
		}
	}
	internal static class ExtractionAreaFix
	{
		internal static void Apply(ExtractionPoint ep, ExtractionPoint vanilla)
		{
			//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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: 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_00de: 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_00ea: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: 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_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			GameObject extractionArea = ep.extractionArea;
			GameObject extractionArea2 = vanilla.extractionArea;
			if (!((Object)(object)extractionArea == (Object)null) && !((Object)(object)extractionArea2 == (Object)null) && !((Object)(object)extractionArea == (Object)(object)extractionArea2))
			{
				MeshFilter component = extractionArea.GetComponent<MeshFilter>();
				MeshFilter component2 = extractionArea2.GetComponent<MeshFilter>();
				if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
				{
					component.sharedMesh = component2.sharedMesh;
				}
				MeshRenderer component3 = extractionArea.GetComponent<MeshRenderer>();
				MeshRenderer component4 = extractionArea2.GetComponent<MeshRenderer>();
				if ((Object)(object)component3 != (Object)null && (Object)(object)component4 != (Object)null)
				{
					((Renderer)component3).sharedMaterials = ((Renderer)component4).sharedMaterials;
					((Renderer)component3).enabled = ((Renderer)component4).enabled;
				}
				Transform transform = ((Component)ep).transform;
				Transform transform2 = ((Component)vanilla).transform;
				Vector3 val = transform2.InverseTransformPoint(extractionArea2.transform.position);
				Quaternion val2 = Quaternion.Inverse(transform2.rotation) * extractionArea2.transform.rotation;
				Vector3 val3 = Divide(extractionArea2.transform.lossyScale, transform2.lossyScale);
				extractionArea.transform.SetPositionAndRotation(transform.TransformPoint(val), transform.rotation * val2);
				Vector3 val4 = Vector3.Scale(val3, transform.lossyScale);
				Transform parent = extractionArea.transform.parent;
				extractionArea.transform.localScale = (((Object)(object)parent != (Object)null) ? Divide(val4, parent.lossyScale) : val4);
			}
		}

		private static Vector3 Divide(Vector3 a, Vector3 b)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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)
			return new Vector3(Mathf.Approximately(b.x, 0f) ? a.x : (a.x / b.x), Mathf.Approximately(b.y, 0f) ? a.y : (a.y / b.y), Mathf.Approximately(b.z, 0f) ? a.z : (a.z / b.z));
		}
	}
	[HarmonyPatch(typeof(LoadingUI), "LevelAnimationStart")]
	internal static class LevelNamePatch
	{
		[HarmonyPostfix]
		private static void Postfix(LoadingUI __instance)
		{
			try
			{
				Level val = (((Object)(object)LevelGenerator.Instance != (Object)null) ? LevelGenerator.Instance.Level : null);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)__instance.levelNameText == (Object)null) && Plugin.Names != null)
				{
					string text = ((TMP_Text)__instance.levelNameText).text;
					if (text == val.NarrativeName && Plugin.Names.TryTranslate(text, out string translated))
					{
						((TMP_Text)__instance.levelNameText).text = translated;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogDebug((object)("Level name failed: " + ex.Message));
			}
		}
	}
	internal sealed class MiniJson
	{
		private readonly string _text;

		private int _pos;

		private MiniJson(string text)
		{
			_text = text;
		}

		internal static object? Parse(string text)
		{
			MiniJson miniJson = new MiniJson(text);
			if (miniJson._pos < text.Length && text[miniJson._pos] == '\ufeff')
			{
				miniJson._pos++;
			}
			object? result = miniJson.ReadValue();
			miniJson.SkipWhitespace();
			if (miniJson._pos < text.Length)
			{
				throw miniJson.Error("unexpected text after the end");
			}
			return result;
		}

		private object? ReadValue()
		{
			SkipWhitespace();
			if (_pos >= _text.Length)
			{
				throw Error("unexpected end of file");
			}
			char c = _text[_pos];
			switch (c)
			{
			case '{':
				return ReadObject();
			case '[':
				return ReadArray();
			case '"':
				return ReadString();
			case 't':
				ReadWord("true");
				return true;
			case 'f':
				ReadWord("false");
				return false;
			case 'n':
				ReadWord("null");
				return null;
			default:
				switch (c)
				{
				case '-':
				case '0':
				case '1':
				case '2':
				case '3':
				case '4':
				case '5':
				case '6':
				case '7':
				case '8':
				case '9':
					return ReadNumber();
				default:
					throw Error($"unexpected character '{c}'");
				}
			}
		}

		private Dictionary<string, object?> ReadObject()
		{
			Dictionary<string, object> dictionary = new Dictionary<string, object>();
			_pos++;
			SkipWhitespace();
			if (Peek() == '}')
			{
				_pos++;
				return dictionary;
			}
			while (true)
			{
				SkipWhitespace();
				if (Peek() != '"')
				{
					break;
				}
				string key = ReadString();
				SkipWhitespace();
				Expect(':');
				dictionary[key] = ReadValue();
				SkipWhitespace();
				switch (Peek())
				{
				case ',':
					break;
				case '}':
					_pos++;
					return dictionary;
				default:
					throw Error("expected ',' or '}' (a comma may be missing)");
				}
				_pos++;
			}
			throw Error("expected a \"name\"");
		}

		private List<object?> ReadArray()
		{
			List<object> list = new List<object>();
			_pos++;
			SkipWhitespace();
			if (Peek() == ']')
			{
				_pos++;
				return list;
			}
			while (true)
			{
				list.Add(ReadValue());
				SkipWhitespace();
				switch (Peek())
				{
				case ',':
					break;
				case ']':
					_pos++;
					return list;
				default:
					throw Error("expected ',' or ']'");
				}
				_pos++;
			}
		}

		private string ReadString()
		{
			_pos++;
			StringBuilder stringBuilder = new StringBuilder();
			while (_pos < _text.Length)
			{
				char c = _text[_pos++];
				switch (c)
				{
				case '"':
					return stringBuilder.ToString();
				case '\n':
					throw Error("a string is not closed with \" before the end of the line");
				default:
					stringBuilder.Append(c);
					break;
				case '\\':
				{
					if (_pos >= _text.Length)
					{
						throw Error("unexpected end of file");
					}
					char c2 = _text[_pos++];
					switch (c2)
					{
					case '"':
						stringBuilder.Append('"');
						break;
					case '\\':
						stringBuilder.Append('\\');
						break;
					case '/':
						stringBuilder.Append('/');
						break;
					case 'b':
						stringBuilder.Append('\b');
						break;
					case 'f':
						stringBuilder.Append('\f');
						break;
					case 'n':
						stringBuilder.Append('\n');
						break;
					case 'r':
						stringBuilder.Append('\r');
						break;
					case 't':
						stringBuilder.Append('\t');
						break;
					case 'u':
					{
						if (_pos + 4 > _text.Length || !int.TryParse(_text.Substring(_pos, 4), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result))
						{
							throw Error("bad \\u escape");
						}
						stringBuilder.Append((char)result);
						_pos += 4;
						break;
					}
					default:
						throw Error($"bad escape '\\{c2}'");
					}
					break;
				}
				}
			}
			throw Error("a string is not closed with \"");
		}

		private double ReadNumber()
		{
			int pos = _pos;
			while (_pos < _text.Length && "+-0123456789.eE".IndexOf(_text[_pos]) >= 0)
			{
				_pos++;
			}
			string text = _text.Substring(pos, _pos - pos);
			if (!double.TryParse(text, NumberStyles.Float, CultureInfo.InvariantCulture, out var result))
			{
				_pos = pos;
				throw Error("bad number '" + text + "'");
			}
			return result;
		}

		private void ReadWord(string word)
		{
			if (string.CompareOrdinal(_text, _pos, word, 0, word.Length) != 0)
			{
				throw Error("unexpected word (did you forget \"quotes\"?)");
			}
			_pos += word.Length;
		}

		private void Expect(char c)
		{
			if (Peek() != c)
			{
				throw Error($"expected '{c}'");
			}
			_pos++;
		}

		private char Peek()
		{
			if (_pos >= _text.Length)
			{
				return '\0';
			}
			return _text[_pos];
		}

		private void SkipWhitespace()
		{
			while (_pos < _text.Length && char.IsWhiteSpace(_text[_pos]))
			{
				_pos++;
			}
		}

		private FormatException Error(string message)
		{
			int num = 1;
			int num2 = 1;
			for (int i = 0; i < _pos && i < _text.Length; i++)
			{
				if (_text[i] == '\n')
				{
					num++;
					num2 = 1;
				}
				else
				{
					num2++;
				}
			}
			return new FormatException($"{message} (line {num}, column {num2})");
		}
	}
	internal sealed class NameTable
	{
		private const float ReloadCheckInterval = 2f;

		private readonly ManualLogSource _log;

		private readonly string _path;

		private readonly string _fileName;

		private readonly string _label;

		private DateTime _loadedWriteTime;

		private float _nextReloadCheck;

		private Dictionary<string, Dictionary<string, string>> _tables = NewTables();

		private string? _cachedLocale;

		private Dictionary<string, string>? _cachedTable;

		private readonly HashSet<string> _reported = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		internal NameTable(ManualLogSource log, string path, string defaultJson, string label, params string[] legacyPaths)
		{
			_log = log;
			_path = path;
			_fileName = Path.GetFileName(path);
			_label = label;
			try
			{
				if (!File.Exists(path))
				{
					string text = Array.Find(legacyPaths, File.Exists);
					if (text != null)
					{
						File.Copy(text, path);
						_log.LogInfo((object)("Copied " + Path.GetFileName(text) + " to " + _fileName));
					}
					else
					{
						File.WriteAllText(path, defaultJson, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
						_log.LogInfo((object)("Created " + path));
					}
				}
			}
			catch (Exception ex)
			{
				_log.LogError((object)("Could not create " + path + ": " + ex.Message));
			}
			Load();
		}

		internal bool TryTranslate(string name, out string translated)
		{
			translated = name;
			try
			{
				ReloadIfChanged();
				Dictionary<string, string> dictionary = CurrentTable();
				if (dictionary != null && dictionary.TryGetValue(name.Trim(), out var value) && !string.IsNullOrEmpty(value))
				{
					translated = value;
					return true;
				}
			}
			catch (Exception arg)
			{
				if (_reported.Add("\0error"))
				{
					_log.LogError((object)$"Translate failed: {arg}");
				}
			}
			return false;
		}

		internal void ReportIfMissing(string name)
		{
			try
			{
				if (!string.IsNullOrEmpty(name))
				{
					Dictionary<string, string> dictionary = CurrentTable();
					if (dictionary != null && !dictionary.ContainsKey(name.Trim()) && _reported.Add(name.Trim()))
					{
						_log.LogDebug((object)("No translation for \"" + name.Trim() + "\" (language " + SemiFunc.LocaleGetCode() + "). Add it to " + _fileName + " if you want."));
					}
				}
			}
			catch (Exception ex)
			{
				_log.LogDebug((object)("ReportIfMissing failed: " + ex.Message));
			}
		}

		private Dictionary<string, string>? CurrentTable()
		{
			string text = SemiFunc.LocaleGetCode() ?? "";
			if (text == _cachedLocale)
			{
				return _cachedTable;
			}
			_cachedLocale = text;
			_cachedTable = null;
			if (_tables.TryGetValue(text, out Dictionary<string, string> value))
			{
				_cachedTable = value;
			}
			else
			{
				int num = text.IndexOf('-');
				if (num > 0 && _tables.TryGetValue(text.Substring(0, num), out Dictionary<string, string> value2))
				{
					_cachedTable = value2;
				}
			}
			return _cachedTable;
		}

		private void ReloadIfChanged()
		{
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			if (!(realtimeSinceStartup < _nextReloadCheck))
			{
				_nextReloadCheck = realtimeSinceStartup + 2f;
				if (File.Exists(_path) && File.GetLastWriteTimeUtc(_path) != _loadedWriteTime)
				{
					Load();
				}
			}
		}

		private void Load()
		{
			try
			{
				if (!File.Exists(_path))
				{
					_log.LogWarning((object)(_path + " not found. No names are translated."));
					return;
				}
				_loadedWriteTime = File.GetLastWriteTimeUtc(_path);
				string text = File.ReadAllText(_path, Encoding.UTF8);
				Dictionary<string, Dictionary<string, string>> dictionary = (_tables = Parse(text));
				_cachedLocale = null;
				_cachedTable = null;
				_reported.Clear();
				List<string> list = new List<string>();
				foreach (KeyValuePair<string, Dictionary<string, string>> item in dictionary)
				{
					list.Add($"{item.Key}={item.Value.Count}");
				}
				_log.LogInfo((object)(_label + ": loaded " + _fileName + " (" + ((list.Count > 0) ? string.Join(", ", list) : "no languages") + ")"));
			}
			catch (Exception ex)
			{
				_log.LogError((object)("Could not read " + _path + ": " + ex.Message + " (keeping the previous names)"));
			}
		}

		private Dictionary<string, Dictionary<string, string>> Parse(string text)
		{
			Dictionary<string, object> obj = (MiniJson.Parse(text) as Dictionary<string, object>) ?? throw new FormatException("the top level must be { ... }");
			Dictionary<string, Dictionary<string, string>> dictionary = NewTables();
			foreach (KeyValuePair<string, object> item in obj)
			{
				if (item.Key.StartsWith("_", StringComparison.Ordinal) || !(item.Value is Dictionary<string, object> dictionary2))
				{
					continue;
				}
				Dictionary<string, string> dictionary3 = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
				foreach (KeyValuePair<string, object> item2 in dictionary2)
				{
					if (!item2.Key.StartsWith("_", StringComparison.Ordinal))
					{
						if (item2.Value is string value)
						{
							dictionary3[item2.Key.Trim()] = value;
						}
						else
						{
							_log.LogWarning((object)(item.Key + ".\"" + item2.Key + "\": the value must be a string in \"quotes\" (ignored)"));
						}
					}
				}
				dictionary[item.Key.Trim()] = dictionary3;
			}
			return dictionary;
		}

		private static Dictionary<string, Dictionary<string, string>> NewTables()
		{
			return new Dictionary<string, Dictionary<string, string>>(StringComparer.OrdinalIgnoreCase);
		}
	}
	[BepInPlugin("Midorino.EchoholdFixPlus", "Echohold_Fix_Plus", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public sealed class Plugin : BaseUnityPlugin
	{
		public enum UnstickMode
		{
			Off,
			EchoholdOnly,
			All
		}

		public const string Guid = "Midorino.EchoholdFixPlus";

		public const string Name = "Echohold_Fix_Plus";

		public const string Version = "1.0.0";

		public const string LocalizeFileName = "Echohold_Fix_Plus.Localize.json";

		private const string DefaultLocalizeJson = "{\n  \"_readme\": \"Level names on the loading screen per game language (ja = Japanese). Left: English level name, right: name to show. Add other languages the same way. Keys starting with _ are ignored. Changes are reloaded while the game is running.\",\n  \"ja\": {\n    \"Echohold Station\": \"エコーホールド・ステーション\"\n  }\n}\n";

		internal static NameTable? Names;

		internal static ConfigEntry<UnstickMode> UnstickValuables;

		internal static ConfigEntry<bool> FixDroneTargeting;

		internal static ConfigEntry<bool> LayDownUnderLowCeiling;

		internal static ConfigEntry<float> LowCeilingGap;

		internal static ConfigEntry<bool> FixExtractionArea;

		private const string EchoholdFixGuid = "empress.repo.echoholdcompatpatch";

		internal const string EchoholdLevelName = "Level - Echohold";

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			UnstickValuables = ((BaseUnityPlugin)this).Config.Bind<UnstickMode>("Valuables", "UnstickValuables", UnstickMode.EchoholdOnly, "Push valuables out of walls/floors when the level starts. EchoholdOnly = Echohold valuables on any level. All = every valuable.");
			FixDroneTargeting = ((BaseUnityPlugin)this).Config.Bind<bool>("Valuables", "FixDroneTargeting", true, "Let drones target Echohold valuables (e.g. Plant Container, Alien Canister) that the game's line-of-sight check misses.");
			LayDownUnderLowCeiling = ((BaseUnityPlugin)this).Config.Bind<bool>("Valuables", "LayDownUnderLowCeiling", true, "On Echohold, lay tall valuables (e.g. server rack, cryo pod) on their side when the ceiling above them is too low to carry them out.");
			LowCeilingGap = ((BaseUnityPlugin)this).Config.Bind<float>("Valuables", "LowCeilingGap", 0.5f, "Space (m) above a tall valuable below which it is laid down.");
			FixExtractionArea = ((BaseUnityPlugin)this).Config.Bind<bool>("Extraction", "FixExtractionArea", true, "Use the vanilla look for the red extraction area shown during the extraction alarm.");
			Names = new NameTable(Log, Path.Combine(Paths.ConfigPath, "Echohold_Fix_Plus.Localize.json"), "{\n  \"_readme\": \"Level names on the loading screen per game language (ja = Japanese). Left: English level name, right: name to show. Add other languages the same way. Keys starting with _ are ignored. Changes are reloaded while the game is running.\",\n  \"ja\": {\n    \"Echohold Station\": \"エコーホールド・ステーション\"\n  }\n}\n", "Echohold_Fix_Plus 1.0.0");
			new Harmony("Midorino.EchoholdFixPlus").PatchAll(typeof(Plugin).Assembly);
		}

		internal static bool IsEchoholdLevel()
		{
			Level val = (((Object)(object)RunManager.instance != (Object)null) ? RunManager.instance.levelCurrent : null);
			if ((Object)(object)val != (Object)null)
			{
				return string.Equals(((Object)val).name, "Level - Echohold", StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}
	}
	internal static class VanillaTemplates
	{
		private static bool _searched;

		private static ExtractionPoint? _extractionPoint;

		private static Transform? _chargeArea;

		private static readonly string[] FallbackStartRoomPaths = new string[4] { "level/arctic/start room/Start Room - Arctic - Lobby", "level/wizard/start room/Start Room - Wizard - Chairs", "level/museum/start room/Start Room - Museum - Column", "level/desert/start room/Start Room - Desert - Exit" };

		public static ExtractionPoint? ExtractionPoint
		{
			get
			{
				Search();
				return _extractionPoint;
			}
		}

		public static Transform? ChargeArea
		{
			get
			{
				Search();
				return _chargeArea;
			}
		}

		private static bool Done
		{
			get
			{
				if ((Object)(object)_extractionPoint != (Object)null)
				{
					return (Object)(object)_chargeArea != (Object)null;
				}
				return false;
			}
		}

		private static void Search()
		{
			//IL_021e: 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)
			if (_searched)
			{
				return;
			}
			_searched = true;
			int num = 0;
			int num2 = 0;
			int num3 = 0;
			try
			{
				if ((Object)(object)RunManager.instance != (Object)null && RunManager.instance.levels != null)
				{
					foreach (Level level in RunManager.instance.levels)
					{
						if ((Object)(object)level == (Object)null || level.StartRooms == null || string.Equals(((Object)level).name, "Level - Echohold", StringComparison.OrdinalIgnoreCase))
						{
							continue;
						}
						num++;
						foreach (PrefabRef startRoom in level.StartRooms)
						{
							num2++;
							GameObject val = TryGetPrefab(startRoom);
							if (!((Object)(object)val == (Object)null))
							{
								num3++;
								Inspect(val);
								if (Done)
								{
									break;
								}
							}
						}
						if (Done)
						{
							break;
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Searching level start rooms failed: " + ex.GetType().Name + ": " + ex.Message));
			}
			Plugin.Log.LogDebug((object)$"Vanilla template search: {num} level(s), {num2} start room(s), {num3} loaded");
			string[] fallbackStartRoomPaths = FallbackStartRoomPaths;
			foreach (string text in fallbackStartRoomPaths)
			{
				if (Done)
				{
					break;
				}
				try
				{
					GameObject val2 = Resources.Load<GameObject>(text);
					Plugin.Log.LogDebug((object)("Resources.Load(\"" + text + "\") -> " + (((Object)(object)val2 != (Object)null) ? "ok" : "not found")));
					if ((Object)(object)val2 != (Object)null)
					{
						Inspect(val2);
					}
				}
				catch (Exception ex2)
				{
					Plugin.Log.LogWarning((object)("Resources.Load(\"" + text + "\") failed: " + ex2.Message));
				}
			}
			if (Done)
			{
				return;
			}
			ExtractionPoint[] array = Resources.FindObjectsOfTypeAll<ExtractionPoint>();
			foreach (ExtractionPoint val3 in array)
			{
				if ((Object)(object)val3 != (Object)null)
				{
					Scene scene = ((Component)val3).gameObject.scene;
					if (!((Scene)(ref scene)).IsValid() && !IsEchohold(((Component)val3).transform))
					{
						Inspect(((Component)((Component)val3).transform.root).gameObject);
					}
				}
			}
		}

		private static GameObject? TryGetPrefab(PrefabRef? prefabRef)
		{
			if (prefabRef == null)
			{
				return null;
			}
			try
			{
				if (((PrefabRef<GameObject>)(object)prefabRef).IsValid())
				{
					return ((PrefabRef<GameObject>)(object)prefabRef).Prefab;
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("PrefabRef '" + ((PrefabRef<GameObject>)(object)prefabRef).PrefabName + "' could not be loaded: " + ex.Message));
			}
			return null;
		}

		private static void Inspect(GameObject prefab)
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)prefab == (Object)null || IsEchohold(prefab.transform))
			{
				return;
			}
			if ((Object)(object)_extractionPoint == (Object)null)
			{
				ExtractionPoint componentInChildren = prefab.GetComponentInChildren<ExtractionPoint>(true);
				if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.localizedBigMessageExtractionActivated != (Object)null && (Object)(object)componentInChildren.emojiScreen != (Object)null)
				{
					_extractionPoint = componentInChildren;
					Plugin.Log.LogDebug((object)("Vanilla extraction point template: " + ((Object)prefab).name));
				}
			}
			if (!((Object)(object)_chargeArea == (Object)null))
			{
				return;
			}
			ChargingStation[] componentsInChildren = prefab.GetComponentsInChildren<ChargingStation>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Transform val = FindChild(((Component)componentsInChildren[i]).transform, "Charge Area");
				if ((Object)(object)val != (Object)null)
				{
					_chargeArea = val;
					Plugin.Log.LogDebug((object)$"Vanilla charge area template: {((Object)prefab).name} scale={val.localScale}");
					break;
				}
			}
		}

		private static bool IsEchohold(Transform t)
		{
			return ((Object)t.root).name.IndexOf("echohold", StringComparison.OrdinalIgnoreCase) >= 0;
		}

		internal static Transform? FindChild(Transform root, string name)
		{
			return ((IEnumerable<Transform>)((Component)root).GetComponentsInChildren<Transform>(true)).FirstOrDefault((Func<Transform, bool>)((Transform t) => (Object)(object)t != (Object)null && string.Equals(((Object)t).name, name, StringComparison.OrdinalIgnoreCase)));
		}
	}
	[HarmonyPatch(typeof(ExtractionPoint), "Start")]
	internal static class ExtractionPointStartPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(ExtractionPoint __instance)
		{
			if ((Object)(object)__instance == (Object)null || !Plugin.IsEchoholdLevel())
			{
				return;
			}
			try
			{
				ExtractionPoint extractionPoint = VanillaTemplates.ExtractionPoint;
				if ((Object)(object)extractionPoint == (Object)null)
				{
					Plugin.Log.LogWarning((object)"No vanilla extraction point found; extraction texts are not fixed.");
					FixEmojiSpritesByName(__instance);
					return;
				}
				int num = 0;
				num += Copy(ref __instance.localizedExtractionCompleted, extractionPoint.localizedExtractionCompleted);
				num += Copy(ref __instance.localizedExtractionExtracting, extractionPoint.localizedExtractionExtracting);
				num += Copy(ref __instance.localizedExtractionLocked, extractionPoint.localizedExtractionLocked);
				num += Copy(ref __instance.localizedExtractionReady, extractionPoint.localizedExtractionReady);
				num += Copy(ref __instance.localizedExtractionActive, extractionPoint.localizedExtractionActive);
				num += Copy(ref __instance.localizedExtractionTaxReturn, extractionPoint.localizedExtractionTaxReturn);
				num += Copy(ref __instance.localizedBigMessageExtractionActivated, extractionPoint.localizedBigMessageExtractionActivated);
				num += Copy(ref __instance.localizedBigMessageExtractionCompleted, extractionPoint.localizedBigMessageExtractionCompleted);
				num += Copy(ref __instance.localizedFocusFillValuables, extractionPoint.localizedFocusFillValuables);
				num += Copy(ref __instance.localizedFocusAvoidGrenades, extractionPoint.localizedFocusAvoidGrenades);
				num += Copy(ref __instance.localizedFocusFindNext, extractionPoint.localizedFocusFindNext);
				num += Copy(ref __instance.localizedFocusBackToTruck, extractionPoint.localizedFocusBackToTruck);
				if (num > 0)
				{
					__instance.RefreshLocalizations();
				}
				CopyTextLayout((TMP_Text?)(object)__instance.haulGoalScreen, (TMP_Text?)(object)extractionPoint.haulGoalScreen, copyRect: false);
				CopyTextLayout((TMP_Text?)(object)__instance.tubeScreenText, (TMP_Text?)(object)extractionPoint.tubeScreenText, copyRect: true);
				if (Plugin.FixExtractionArea.Value)
				{
					ExtractionAreaFix.Apply(__instance, extractionPoint);
				}
				bool flag = false;
				if ((Object)(object)__instance.emojiScreen != (Object)null && (Object)(object)extractionPoint.emojiScreen != (Object)null && (Object)(object)((TMP_Text)extractionPoint.emojiScreen).spriteAsset != (Object)null && (Object)(object)((TMP_Text)__instance.emojiScreen).spriteAsset != (Object)(object)((TMP_Text)extractionPoint.emojiScreen).spriteAsset)
				{
					((TMP_Text)__instance.emojiScreen).spriteAsset = ((TMP_Text)extractionPoint.emojiScreen).spriteAsset;
					flag = true;
				}
				Plugin.Log.LogDebug((object)$"Extraction point '{((Object)__instance).name}': {num} localized text(s) copied, emoji sprites fixed={flag}");
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Fixing extraction point failed: " + ex.Message));
			}
		}

		private static void CopyTextLayout(TMP_Text? target, TMP_Text? source, bool copyRect)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: 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_00d4: 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_0038: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)target == (Object)null) && !((Object)(object)source == (Object)null))
			{
				if (copyRect)
				{
					target.rectTransform.sizeDelta = source.rectTransform.sizeDelta;
					target.rectTransform.pivot = source.rectTransform.pivot;
				}
				target.font = source.font;
				target.fontSharedMaterial = source.fontSharedMaterial;
				target.enableAutoSizing = source.enableAutoSizing;
				target.fontSize = source.fontSize;
				target.fontSizeMin = source.fontSizeMin;
				target.fontSizeMax = source.fontSizeMax;
				target.alignment = source.alignment;
				target.characterSpacing = source.characterSpacing;
				target.wordSpacing = source.wordSpacing;
				target.lineSpacing = source.lineSpacing;
				target.textWrappingMode = source.textWrappingMode;
				target.overflowMode = source.overflowMode;
				target.margin = source.margin;
			}
		}

		private static void FixEmojiSpritesByName(ExtractionPoint ep)
		{
			if (!((Object)(object)ep.emojiScreen == (Object)null))
			{
				TMP_SpriteAsset current = ((TMP_Text)ep.emojiScreen).spriteAsset;
				TMP_SpriteAsset val = ((IEnumerable<TMP_SpriteAsset>)Resources.FindObjectsOfTypeAll<TMP_SpriteAsset>()).FirstOrDefault((Func<TMP_SpriteAsset, bool>)((TMP_SpriteAsset s) => (Object)(object)s != (Object)null && (Object)(object)s != (Object)(object)current && string.Equals(((Object)s).name, "emojis Extraction Point", StringComparison.OrdinalIgnoreCase)));
				if ((Object)(object)val != (Object)null)
				{
					((TMP_Text)ep.emojiScreen).spriteAsset = val;
					Plugin.Log.LogDebug((object)("Extraction point '" + ((Object)ep).name + "': emoji sprites fixed by name"));
				}
				else
				{
					Plugin.Log.LogWarning((object)("Extraction point '" + ((Object)ep).name + "': game emoji sprites not found"));
				}
			}
		}

		private static int Copy(ref LocalizedAsset target, LocalizedAsset? source)
		{
			if ((Object)(object)source == (Object)null || (Object)(object)target == (Object)(object)source)
			{
				return 0;
			}
			target = source;
			return 1;
		}
	}
	[HarmonyPatch(typeof(StartRoom), "Start")]
	internal static class StartRoomStartPatch
	{
		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(StartRoom __instance)
		{
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: 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_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || !Plugin.IsEchoholdLevel())
			{
				return;
			}
			try
			{
				Transform chargeArea = VanillaTemplates.ChargeArea;
				if ((Object)(object)chargeArea == (Object)null)
				{
					Plugin.Log.LogWarning((object)"No vanilla charge area found; truck charger range is not fixed.");
					return;
				}
				ChargingStation[] componentsInChildren = ((Component)__instance).GetComponentsInChildren<ChargingStation>(true);
				foreach (ChargingStation val in componentsInChildren)
				{
					if (string.Equals(((Object)val).name, "Charging Station New", StringComparison.OrdinalIgnoreCase))
					{
						Transform val2 = VanillaTemplates.FindChild(((Component)val).transform, "Charge Area");
						if (!((Object)(object)val2 == (Object)null))
						{
							Vector3 localScale = val2.localScale;
							val2.localScale = chargeArea.localScale;
							val2.localPosition = chargeArea.localPosition;
							val2.localRotation = chargeArea.localRotation;
							Plugin.Log.LogDebug((object)$"Truck charge area: {localScale} -> {val2.localScale}");
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Fixing truck charger failed: " + ex.Message));
			}
		}
	}
	[HarmonyPatch(typeof(ValuableObject), "Start")]
	internal static class ValuableFixes
	{
		private static readonly Regex EchoholdValuableName = new Regex("(^|[\\s\\-_])EH([\\s\\-_]|$)", RegexOptions.Compiled);

		private static readonly HashSet<string> LoggedLayerFix = new HashSet<string>(StringComparer.OrdinalIgnoreCase);

		internal static string TypeName(Component valuable)
		{
			return ((Object)valuable).name.Replace("(Clone)", string.Empty).Trim();
		}

		internal static bool IsEchoholdValuable(Component valuable)
		{
			return EchoholdValuableName.IsMatch(TypeName(valuable));
		}

		[HarmonyPostfix]
		[HarmonyPriority(0)]
		private static void Postfix(ValuableObject __instance)
		{
			try
			{
				if (!((Object)(object)__instance == (Object)null))
				{
					string name = TypeName((Component)(object)__instance);
					bool flag = IsEchoholdValuable((Component)(object)__instance);
					if (flag && Plugin.FixDroneTargeting.Value)
					{
						FixSelfBlockingColliders(__instance, name);
					}
					Plugin.UnstickMode value = Plugin.UnstickValuables.Value;
					bool flag2 = value == Plugin.UnstickMode.All || (value == Plugin.UnstickMode.EchoholdOnly && flag);
					bool flag3 = Plugin.LayDownUnderLowCeiling.Value && Plugin.IsEchoholdLevel();
					if (flag2 || flag3)
					{
						((MonoBehaviour)__instance).StartCoroutine(PlaceWhenLevelReady(__instance, name, flag2, flag3));
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Valuable fix failed: " + ex.Message));
			}
		}

		private static void FixSelfBlockingColliders(ValuableObject valuable, string name)
		{
			int num = LayerMask.NameToLayer("Default");
			int num2 = LayerMask.NameToLayer("PhysGrabObject");
			if (num < 0 || num2 < 0)
			{
				return;
			}
			int num3 = 0;
			Collider[] componentsInChildren = ((Component)valuable).GetComponentsInChildren<Collider>(true);
			foreach (Collider val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && !val.isTrigger && ((Component)val).gameObject.layer == num)
				{
					((Component)val).gameObject.layer = num2;
					num3++;
				}
			}
			if (num3 > 0 && LoggedLayerFix.Add(name))
			{
				Plugin.Log.LogDebug((object)$"{name}: {num3} collider(s) moved from Default to PhysGrabObject layer (drones can target it)");
			}
		}

		private static IEnumerator PlaceWhenLevelReady(ValuableObject valuable, string name, bool unstick, bool layDown)
		{
			while ((Object)(object)LevelGenerator.Instance == (Object)null || !LevelGenerator.Instance.Generated)
			{
				yield return null;
			}
			if ((Object)(object)valuable == (Object)null || !SemiFunc.IsMasterClientOrSingleplayer())
			{
				yield break;
			}
			try
			{
				ValuablePlacement.Fix(valuable, name, unstick, layDown);
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)(name + ": placement fix failed: " + ex.Message));
			}
		}
	}
	internal static class ValuablePlacement
	{
		private readonly struct Pose
		{
			public readonly Quaternion Rotation;

			public readonly Vector3 Pivot;

			public readonly Vector3 Offset;

			public readonly string Label;

			public readonly float Penalty;

			public float Score => ((Vector3)(ref Offset)).magnitude + Penalty;

			public bool IsIdentity
			{
				get
				{
					//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)
					if (Quaternion.Angle(Rotation, Quaternion.identity) < 0.1f)
					{
						return ((Vector3)(ref Offset)).sqrMagnitude < 1E-06f;
					}
					return false;
				}
			}

			public Pose(Quaternion rotation, Vector3 pivot, Vector3 offset, string label, float penalty)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: 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_0009: Unknown result type (might be due to invalid IL or missing references)
				//IL_000f: 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)
				Rotation = rotation;
				Pivot = pivot;
				Offset = offset;
				Label = label;
				Penalty = penalty;
			}

			public Pose WithOffset(Vector3 offset)
			{
				//IL_0001: 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)
				return new Pose(Rotation, Pivot, offset, Label, Penalty);
			}

			public Vector3 Point(Vector3 p)
			{
				//IL_0001: 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_000e: 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_0018: Unknown result type (might be due to invalid IL or missing references)
				//IL_001d: 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_0028: Unknown result type (might be due to invalid IL or missing references)
				return Pivot + Rotation * (p - Pivot) + Offset;
			}
		}

		private sealed class Shape
		{
			public Collider[] Own;

			public HashSet<Collider> OwnSet;

			public Vector3 Origin;

			public Bounds Box;

			public Bounds ColliderBox;

			public Vector3[] Points;

			public int Mask;
		}

		private struct Check
		{
			public float Depth;

			public Vector3 Direction;

			public int Hidden;

			public bool Ok
			{
				get
				{
					if (Depth < 0.03f)
					{
						return Hidden == 0;
					}
					return false;
				}
			}
		}

		private const float Tolerance = 0.03f;

		private const float Margin = 0.01f;

		private const float MaxMove = 1.5f;

		private const float TallHeight = 1.2f;

		private const float BoxShrink = 0.03f;

		private static readonly Vector3[] Offsets = BuildOffsets();

		private static readonly Dictionary<int, int> LayerMasks = new Dictionary<int, int>();

		private static Vector3[] BuildOffsets()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: 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)
			List<Vector3> list = new List<Vector3>();
			float[] array = new float[6] { 0f, 0.05f, 0.1f, 0.2f, 0.3f, 0.5f };
			foreach (float num in array)
			{
				list.Add(Vector3.up * num);
				for (int j = 1; j <= 10; j++)
				{
					float num2 = (float)j * 0.1f;
					for (int k = 0; k < 8; k++)
					{
						float num3 = (float)k * 45f * (MathF.PI / 180f);
						list.Add(new Vector3(Mathf.Cos(num3) * num2, num, Mathf.Sin(num3) * num2));
					}
				}
			}
			return list.OrderBy((Vector3 v) => ((Vector3)(ref v)).magnitude).ToArray();
		}

		internal static void Fix(ValuableObject valuable, string name, bool unstick, bool layDown)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//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_0060: 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_0097: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: 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_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: 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_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: 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_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: 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_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: 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_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_030d: Unknown result type (might be due to invalid IL or missing references)
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0300: Unknown result type (might be due to invalid IL or missing references)
			//IL_0302: Unknown result type (might be due to invalid IL or missing references)
			Shape shape = BuildShape(valuable);
			if (shape == null)
			{
				return;
			}
			Physics.SyncTransforms();
			Pose pose = new Pose(Quaternion.identity, ((Bounds)(ref shape.Box)).center, Vector3.zero, "", 0f);
			Check check = Evaluate(shape, pose);
			bool flag = unstick && !check.Ok;
			float num = CeilingGap(shape);
			bool flag2 = layDown && ((Bounds)(ref shape.ColliderBox)).size.y >= 1.2f && num < Plugin.LowCeilingGap.Value;
			if (!flag && !flag2)
			{
				return;
			}
			Vector3 center = ((Bounds)(ref shape.Box)).center;
			Transform transform = ((Component)valuable).transform;
			List<Pose> rotations = new List<Pose>
			{
				new Pose(Quaternion.AngleAxis(90f, transform.right), center, Vector3.zero, "laid down", 0f),
				new Pose(Quaternion.AngleAxis(-90f, transform.right), center, Vector3.zero, "laid down", 0f),
				new Pose(Quaternion.AngleAxis(90f, transform.forward), center, Vector3.zero, "laid down", 0.05f),
				new Pose(Quaternion.AngleAxis(-90f, transform.forward), center, Vector3.zero, "laid down", 0.05f)
			};
			List<Pose> rotations2 = new List<Pose>
			{
				pose,
				new Pose(Quaternion.AngleAxis(180f, Vector3.up), center, Vector3.zero, "turned 180", 0.25f),
				new Pose(Quaternion.AngleAxis(90f, Vector3.up), center, Vector3.zero, "turned 90", 0.3f),
				new Pose(Quaternion.AngleAxis(-90f, Vector3.up), center, Vector3.zero, "turned 90", 0.3f)
			};
			Pose? pose2 = null;
			if (flag2)
			{
				pose2 = SearchFree(shape, rotations) ?? Resolve(shape, rotations);
			}
			if (!pose2.HasValue && flag)
			{
				pose2 = SearchFree(shape, rotations2) ?? Resolve(shape, rotations2);
			}
			if (!pose2.HasValue)
			{
				Plugin.Log.LogDebug((object)$"{name}: no free spot found (depth {check.Depth:F2} m, hidden parts {check.Hidden}, ceiling gap {num:F2} m)");
				return;
			}
			Pose pose3 = Settle(shape, pose2.Value);
			if (!pose3.IsIdentity)
			{
				Vector3 val = pose3.Point(transform.position);
				Quaternion val2 = pose3.Rotation * transform.rotation;
				Vector3 val3 = val - transform.position;
				float magnitude = ((Vector3)(ref val3)).magnitude;
				PhysGrabObject component = ((Component)valuable).GetComponent<PhysGrabObject>();
				if ((Object)(object)component != (Object)null)
				{
					component.Teleport(val, val2);
				}
				else
				{
					transform.SetPositionAndRotation(val, val2);
				}
				string text = ((pose3.Label == "laid down") ? $"only {num:F2} m to the ceiling" : ($"{check.Depth:F2} m inside a wall/floor" + ((check.Hidden > 0) ? $", {check.Hidden} part(s) through a wall" : string.Empty)));
				string text2 = (string.IsNullOrEmpty(pose3.Label) ? string.Empty : (pose3.Label + ", "));
				Plugin.Log.LogDebug((object)$"{name}: {text} -> {text2}moved {magnitude:F2} m");
			}
		}

		private static Shape? BuildShape(ValuableObject valuable)
		{
			//IL_0069: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_0157: 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_0166: 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_0171: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			Collider[] array = (from c in ((Component)valuable).GetComponentsInChildren<Collider>()
				where (Object)(object)c != (Object)null && c.enabled && !c.isTrigger
				select c).ToArray();
			if (array.Length == 0)
			{
				return null;
			}
			Renderer[] array2 = (from r in ((Component)valuable).GetComponentsInChildren<Renderer>()
				where (Object)(object)r != (Object)null && r.enabled && ((Component)r).gameObject.activeInHierarchy && (r is MeshRenderer || r is SkinnedMeshRenderer)
				select r).ToArray();
			Bounds bounds = array[0].bounds;
			Collider[] array3 = array;
			foreach (Collider val in array3)
			{
				((Bounds)(ref bounds)).Encapsulate(val.bounds);
			}
			Bounds box = bounds;
			Renderer[] array4 = array2;
			foreach (Renderer val2 in array4)
			{
				((Bounds)(ref box)).Encapsulate(val2.bounds);
			}
			List<Vector3> list = new List<Vector3> { ((Bounds)(ref box)).center };
			list.AddRange(array.Select(delegate(Collider c)
			{
				//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_0009: Unknown result type (might be due to invalid IL or missing references)
				Bounds bounds2 = c.bounds;
				return ((Bounds)(ref bounds2)).center;
			}));
			list.AddRange(array2.Select(delegate(Renderer r)
			{
				//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_0009: Unknown result type (might be due to invalid IL or missing references)
				Bounds bounds2 = r.bounds;
				return ((Bounds)(ref bounds2)).center;
			}));
			return new Shape
			{
				Own = array,
				OwnSet = new HashSet<Collider>(array),
				Origin = ((Component)valuable).transform.position + Vector3.up * 0.05f,
				Box = box,
				ColliderBox = bounds,
				Points = list.ToArray(),
				Mask = CollidingLayers(((Component)array[0]).gameObject.layer)
			};
		}

		private static Pose? SearchFree(Shape shape, List<Pose> rotations)
		{
			//IL_0027: 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_0030: Unknown result type (might be due to invalid IL or missing references)
			Pose? result = null;
			foreach (Pose rotation in rotations)
			{
				Vector3[] offsets = Offsets;
				foreach (Vector3 offset in offsets)
				{
					Pose pose = rotation.WithOffset(offset);
					if (result.HasValue && pose.Score >= result.Value.Score)
					{
						break;
					}
					if (BoxFree(shape, pose) && Evaluate(shape, pose).Ok)
					{
						result = pose;
						break;
					}
				}
			}
			return result;
		}

		private static Pose? Resolve(Shape shape, List<Pose> rotations)
		{
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: 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_003f: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_00cb: Unknown result type (might be due to invalid IL or missing references)
			foreach (Pose rotation in rotations)
			{
				Check check = Evaluate(shape, rotation);
				if (check.Ok)
				{
					return rotation;
				}
				Vector3 val = Vector3.zero;
				for (int i = 0; i < 12; i++)
				{
					if (!(check.Depth >= 0.03f))
					{
						break;
					}
					if (!(((Vector3)(ref val)).magnitude <= 1.5f))
					{
						break;
					}
					val += check.Direction * (check.Depth + 0.01f);
					check = Evaluate(shape, rotation.WithOffset(val));
				}
				if (check.Ok && ((Vector3)(ref val)).magnitude <= 1.5f)
				{
					return rotation.WithOffset(val);
				}
				for (float num = 0.1f; num <= 1.501f; num += 0.1f)
				{
					Pose pose = rotation.WithOffset(Vector3.up * num);
					if (Evaluate(shape, pose).Ok)
					{
						return pose;
					}
				}
			}
			return null;
		}

		private static Check Evaluate(Shape shape, Pose pose)
		{
			//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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: 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_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: 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_00c6: 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_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: 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_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_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			Check result = new Check
			{
				Depth = 0f,
				Direction = Vector3.up,
				Hidden = 0
			};
			Collider[] own = shape.Own;
			Vector3 direction = default(Vector3);
			float num2 = default(float);
			foreach (Collider val in own)
			{
				int num = CollidingLayers(((Component)val).gameObject.layer);
				Bounds bounds = val.bounds;
				Vector3 val2 = pose.Point(((Bounds)(ref bounds)).center);
				Quaternion rotation = pose.Rotation;
				bounds = val.bounds;
				Vector3 val3 = RotatedExtents(rotation, ((Bounds)(ref bounds)).extents) + Vector3.one * 0.01f;
				Vector3 val4 = pose.Point(((Component)val).transform.position);
				Quaternion val5 = pose.Rotation * ((Component)val).transform.rotation;
				Collider[] array = Physics.OverlapBox(val2, val3, Quaternion.identity, num, (QueryTriggerInteraction)1);
				foreach (Collider val6 in array)
				{
					if (IsLevel(val6, shape.OwnSet) && Physics.ComputePenetration(val, val4, val5, val6, ((Component)val6).transform.position, ((Component)val6).transform.rotation, ref direction, ref num2) && num2 > result.Depth)
					{
						result.Depth = num2;
						result.Direction = direction;
					}
				}
			}
			Vector3[] points = shape.Points;
			foreach (Vector3 p in points)
			{
				if (LineBlocked(shape, shape.Origin, pose.Point(p)))
				{
					result.Hidden++;
				}
			}
			return result;
		}

		private static bool BoxFree(Shape shape, Pose pose)
		{
			//IL_0006: 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_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_002e: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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)
			Vector3 val = Vector3.Max(((Bounds)(ref shape.Box)).extents - Vector3.one * 0.03f, Vector3.one * 0.01f);
			Collider[] array = Physics.OverlapBox(pose.Point(((Bounds)(ref shape.Box)).center), val, pose.Rotation, shape.Mask, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				if (IsLevel(array[i], shape.OwnSet))
				{
					return false;
				}
			}
			return true;
		}

		private static bool LineBlocked(Shape shape, Vector3 from, Vector3 to)
		{
			//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_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_001a: 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_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = to - from;
			float magnitude = ((Vector3)(ref val)).magnitude;
			if (magnitude < 0.01f)
			{
				return false;
			}
			RaycastHit[] array = Physics.RaycastAll(from, val / magnitude, magnitude, shape.Mask, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val2 = array[i];
				if (IsLevel(((RaycastHit)(ref val2)).collider, shape.OwnSet))
				{
					return true;
				}
			}
			return false;
		}

		private static float CeilingGap(Shape shape)
		{
			//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_0010: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: 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_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_00a5: 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)
			Bounds colliderBox = shape.ColliderBox;
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(Mathf.Max(0.01f, ((Bounds)(ref colliderBox)).extents.x - 0.05f), 0.01f, Mathf.Max(0.01f, ((Bounds)(ref colliderBox)).extents.z - 0.05f));
			Vector3 val2 = new Vector3(((Bounds)(ref colliderBox)).center.x, ((Bounds)(ref colliderBox)).max.y - 0.02f, ((Bounds)(ref colliderBox)).center.z);
			float num = 10f;
			RaycastHit[] array = Physics.BoxCastAll(val2, val, Vector3.up, Quaternion.identity, 10f, shape.Mask, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val3 = array[i];
				if (((RaycastHit)(ref val3)).distance > 0f && IsLevel(((RaycastHit)(ref val3)).collider, shape.OwnSet))
				{
					num = Mathf.Min(num, ((RaycastHit)(ref val3)).distance);
				}
			}
			return num;
		}

		private static Pose Settle(Shape shape, Pose pose)
		{
			//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_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_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_0047: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			if (pose.IsIdentity)
			{
				return pose;
			}
			Vector3 val = Vector3.Max(((Bounds)(ref shape.ColliderBox)).extents - Vector3.one * 0.02f, Vector3.one * 0.01f);
			Vector3 val2 = pose.Point(((Bounds)(ref shape.ColliderBox)).center);
			float num = float.MaxValue;
			RaycastHit[] array = Physics.BoxCastAll(val2, val, Vector3.down, pose.Rotation, 1.5f, shape.Mask, (QueryTriggerInteraction)1);
			for (int i = 0; i < array.Length; i++)
			{
				RaycastHit val3 = array[i];
				if (((RaycastHit)(ref val3)).distance > 0f && IsLevel(((RaycastHit)(ref val3)).collider, shape.OwnSet))
				{
					num = Mathf.Min(num, ((RaycastHit)(ref val3)).distance);
				}
			}
			float num2 = num - 0.03f;
			if (num == float.MaxValue || num2 <= 0.02f)
			{
				return pose;
			}
			Pose pose2 = pose.WithOffset(pose.Offset + Vector3.down * num2);
			if (!Evaluate(shape, pose2).Ok)
			{
				return pose;
			}
			return pose2;
		}

		private static bool IsLevel(Collider? other, HashSet<Collider> ownSet)
		{
			if ((Object)(object)other != (Object)null && !other.isTrigger && (Object)(object)other.attachedRigidbody == (Object)null)
			{
				return !ownSet.Contains(other);
			}
			return false;
		}

		private static Vector3 RotatedExtents(Quaternion rotation, Vector3 extents)
		{
			//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_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_001b: 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_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0037: 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_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: 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_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = rotation * new Vector3(extents.x, 0f, 0f);
			Vector3 val2 = rotation * new Vector3(0f, extents.y, 0f);
			Vector3 val3 = rotation * new Vector3(0f, 0f, extents.z);
			return new Vector3(Mathf.Abs(val.x) + Mathf.Abs(val2.x) + Mathf.Abs(val3.x), Mathf.Abs(val.y) + Mathf.Abs(val2.y) + Mathf.Abs(val3.y), Mathf.Abs(val.z) + Mathf.Abs(val2.z) + Mathf.Abs(val3.z));
		}

		private static int CollidingLayers(int layer)
		{
			if (LayerMasks.TryGetValue(layer, out var value))
			{
				return value;
			}
			value = 0;
			for (int i = 0; i < 32; i++)
			{
				if (!Physics.GetIgnoreLayerCollision(layer, i))
				{
					value |= 1 << i;
				}
			}
			LayerMasks[layer] = value;
			return value;
		}
	}
}