Decompiled source of ItemInspect v1.1.0

plugins/nixi.ItemInspect.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
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("nixi.ItemInspect")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+ef93c818a9118cd51034b7e3d8dad18a7be2d0b9")]
[assembly: AssemblyProduct("nixi.ItemInspect")]
[assembly: AssemblyTitle("nixi.ItemInspect")]
[assembly: AssemblyVersion("1.1.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 NixiItemInspect
{
	[BepInPlugin("nixi.iteminspect", "Item Inspect", "1.1.0")]
	public class Plugin : BaseUnityPlugin
	{
		public const string Guid = "nixi.iteminspect";

		public const string Name = "Item Inspect";

		public const string Version = "1.1.0";

		internal static ManualLogSource Log;

		private ConfigEntry<KeyCode> _key;

		private ConfigEntry<bool> _loopHold;

		private ConfigEntry<bool> _bringCloser;

		private ConfigEntry<string> _style;

		private ConfigEntry<string> _itemStyles;

		private ConfigEntry<float> _speed;

		private ConfigEntry<float> _intensity;

		private ConfigEntry<float> _smoothing;

		private ConfigEntry<string> _oneHandItems;

		private ConfigEntry<bool> _oneHandSmall;

		private ConfigEntry<bool> _swingEnabled;

		internal static ConfigEntry<string> SwingItems;

		internal static ConfigEntry<bool> ShowPrompt;

		internal static ConfigEntry<string> PromptText;

		internal static ConfigEntry<string> SwingPromptText;

		internal static string KeyName = "F";

		internal static bool Active;

		internal static object InspectedItem;

		internal static Quaternion LocalRot = Quaternion.identity;

		internal static Vector3 LocalPos = Vector3.zero;

		private InspectAnim _anim;

		private float _time;

		private int _lastStyle = -1;

		private Vector3 _eul;

		private Vector3 _eulVel;

		private Vector3 _pos;

		private Vector3 _posVel;

		private const float BridgeTime = 0.8f;

		private float _bridge = -1f;

		private Vector3 _bridgeEul;

		private Vector3 _bridgePos;

		private InputReader _input;

		private MouseReader _mouse;

		private bool _ready;

		private bool _errorLogged;

		internal static void Info(string m)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)m);
			}
			Debug.Log((object)("[ItemInspect] " + m));
		}

		internal static void Error(string m)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)m);
			}
			Debug.LogError((object)("[ItemInspect] " + m));
		}

		private void Awake()
		{
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Expected O, but got Unknown
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Expected O, but got Unknown
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Expected O, but got Unknown
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Expected O, but got Unknown
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Expected O, but got Unknown
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			_key = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "InspectKey", (KeyCode)102, "Клавиша осмотра. Примеры: F, V, G, Alpha5 (цифра 5), LeftAlt, LeftControl, LeftShift, Tab, Mouse2 (колесо), Mouse3, Mouse4 (боковые кнопки мыши)");
			_loopHold = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "LoopWhileHeld", true, "Пока клавиша зажата — осмотр повторяется по кругу");
			_bringCloser = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "BringToCenter", true, "Подносить предмет к центру экрана во время осмотра");
			_style = ((BaseUnityPlugin)this).Config.Bind<string>("Animation", "Style", "Auto", new ConfigDescription("Вариант осмотра. Auto — свой для каждого предмета, Random — случайный", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[9] { "Auto", "Random", "Classic", "Flip", "Toss", "Gentle", "Lift", "Heavy", "Blade" }), Array.Empty<object>()));
			_itemStyles = ((BaseUnityPlugin)this).Config.Bind<string>("Animation", "ItemStyles", "", "Свои правила для режима Auto: часть_названия=Стиль через запятую. Пример: compass=Toss, rope=Gentle");
			_speed = ((BaseUnityPlugin)this).Config.Bind<float>("Animation", "Speed", 1f, new ConfigDescription("Скорость анимации (2 = вдвое быстрее)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.3f, 3f), Array.Empty<object>()));
			_intensity = ((BaseUnityPlugin)this).Config.Bind<float>("Animation", "RotationIntensity", 1f, new ConfigDescription("Множитель углов поворота", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 2f), Array.Empty<object>()));
			_smoothing = ((BaseUnityPlugin)this).Config.Bind<float>("Animation", "Smoothing", 0.3f, new ConfigDescription("Сглаживание движений (0 = точно по кривой, 2 = очень мягко)", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2f), Array.Empty<object>()));
			_oneHandItems = ((BaseUnityPlugin)this).Config.Bind<string>("Hands", "OneHandItems", "berry, mushroom, shroom, egg, apple, nut, seed, granola, candy, cookie, marshmallow, honey, pepper, shell, stone, compass, flare, dart, banana", "Предметы, которые при осмотре берутся в одну (правую) руку: части названий через запятую");
			_oneHandSmall = ((BaseUnityPlugin)this).Config.Bind<bool>("Hands", "OneHandSmallItems", true, "Брать в одну руку любые маленькие предметы (до 30 см), даже если их нет в списке");
			_swingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Swing", "EnableSwing", true, "Взмах ножом по ЛКМ (только визуально и только у предметов без своего действия на ЛКМ)");
			SwingItems = ((BaseUnityPlugin)this).Config.Bind<string>("Swing", "SwingItems", "dagger, ritual, knife, sword, blade", "Какими предметами можно взмахивать: части названий через запятую");
			ShowPrompt = ((BaseUnityPlugin)this).Config.Bind<bool>("Prompt", "ShowPrompt", true, "Показывать подсказки «осмотр» и «взмах» в списке действий с предметом");
			PromptText = ((BaseUnityPlugin)this).Config.Bind<string>("Prompt", "PromptText", "осмотр", "Текст подсказки осмотра");
			SwingPromptText = ((BaseUnityPlugin)this).Config.Bind<string>("Prompt", "SwingPromptText", "взмах", "Текст подсказки взмаха");
			KeyName = InputReader.FromKeyCode(_key.Value);
			try
			{
				Refs.Init();
				_input = new InputReader(KeyName);
				_key.SettingChanged += delegate
				{
					//IL_0006: 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)
					KeyName = InputReader.FromKeyCode(_key.Value);
					_input = new InputReader(KeyName);
					InspectPrompt.RefreshKey();
					Info($"Клавиша осмотра: {_key.Value}");
				};
				_mouse = new MouseReader();
				Harmony val = new Harmony("nixi.iteminspect");
				val.PatchAll(typeof(Patches.HoldForward));
				val.PatchAll(typeof(Patches.HoldUp));
				val.PatchAll(typeof(Patches.AnimationItemTransform));
				val.PatchAll(typeof(Patches.LeftHandIK));
				val.PatchAll(typeof(Patches.BeforeUnattach));
				try
				{
					val.PatchAll(typeof(Patches.ItemPrompts));
				}
				catch (Exception ex)
				{
					Error("Подсказки недоступны: " + ex.Message);
				}
				_ready = true;
				Info(string.Format("{0} {1} загружен. Клавиша осмотра: {2}", "Item Inspect", "1.1.0", _key.Value));
			}
			catch (Exception arg)
			{
				Error(string.Format("{0}: не удалось инициализироваться, мод отключён.\n{1}", "Item Inspect", arg));
			}
		}

		private void Update()
		{
			if (!_ready)
			{
				return;
			}
			try
			{
				Tick();
			}
			catch (Exception arg)
			{
				if (!_errorLogged)
				{
					_errorLogged = true;
					Error(string.Format("{0}: ошибка в Update (дальнейшие не логируются):\n{1}", "Item Inspect", arg));
				}
				ResetAll();
			}
		}

		private void Tick()
		{
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Expected O, but got Unknown
			//IL_0074: 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)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Expected O, but got Unknown
			//IL_01a1: 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_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: 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_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0233: Unknown result type (might be due to invalid IL or missing references)
			//IL_0237: Unknown result type (might be due to invalid IL or missing references)
			//IL_023c: Unknown result type (might be due to invalid IL or missing references)
			//IL_053e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0543: Unknown result type (might be due to invalid IL or missing references)
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_0558: Unknown result type (might be due to invalid IL or missing references)
			//IL_055f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0564: Unknown result type (might be due to invalid IL or missing references)
			//IL_0574: Unknown result type (might be due to invalid IL or missing references)
			//IL_0579: Unknown result type (might be due to invalid IL or missing references)
			//IL_057f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0584: Unknown result type (might be due to invalid IL or missing references)
			//IL_0589: Unknown result type (might be due to invalid IL or missing references)
			//IL_058f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0594: Unknown result type (might be due to invalid IL or missing references)
			//IL_03fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_040b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0410: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_03dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_035e: Unknown result type (might be due to invalid IL or missing references)
			//IL_036e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_037f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_0389: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b8: 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_05aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_05f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0303: Unknown result type (might be due to invalid IL or missing references)
			//IL_0308: Unknown result type (might be due to invalid IL or missing references)
			//IL_045b: Unknown result type (might be due to invalid IL or missing references)
			//IL_04b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_04be: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_04c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ee: Unknown result type (might be due to invalid IL or missing references)
			float num = Mathf.Min(Time.deltaTime, 0.05f);
			object obj = Refs.LocalCharacter();
			object obj2 = ((obj != null) ? Refs.CurrentItem(obj) : null);
			if (_input.WasPressedThisFrame() && obj2 != null && CanStart(obj, obj2))
			{
				bool num2 = Active && obj2 == InspectedItem;
				InspectedItem = obj2;
				_anim = PickAnimation(obj2);
				Active = true;
				if (num2)
				{
					_eul = Wrap(_eul);
					_bridgeEul = _eul;
					_bridgePos = _pos;
					_time = _anim.LoopStart;
					_bridge = 0f;
				}
				else
				{
					_time = 0f;
					_bridge = -1f;
				}
				Stabilizer.Begin(obj, obj2);
				Hands.Begin(obj, obj2, ItemStyles.WantsOneHand((Component)obj2, _oneHandItems.Value, _oneHandSmall.Value));
			}
			if (_swingEnabled.Value && _mouse.LeftPressedThisFrame() && obj2 != null && CanStart(obj, obj2) && ItemStyles.IsSwingItem((Component)obj2, SwingItems.Value))
			{
				StartSwing(obj2);
			}
			Hands.Tick(num);
			if (!Active)
			{
				return;
			}
			if (_anim != null && (obj2 == null || obj2 != InspectedItem || ShouldCancel(obj, obj2)))
			{
				_anim = null;
			}
			if (obj2 == null || obj2 != InspectedItem)
			{
				ResetAll();
				return;
			}
			bool flag = _loopHold.Value && _input.IsHeld();
			Vector3 euler = Vector3.zero;
			Vector3 pos = Vector3.zero;
			if (_anim != null)
			{
				if (_bridge >= 0f)
				{
					_bridge += num * _speed.Value / 0.8f;
					_anim.Evaluate(_time, out var euler2, out var pos2);
					float num3 = InspectAnim.Smooth(_bridge);
					euler = Vector3.Lerp(_bridgeEul, euler2 * _intensity.Value, num3);
					pos = Vector3.Lerp(_bridgePos, pos2, num3);
					if (_bridge >= 1f)
					{
						_bridge = -1f;
					}
				}
				else
				{
					_time += num * _speed.Value;
					if (_anim.IsSwing && _time >= _anim.Duration)
					{
						if (_swingEnabled.Value && _mouse.LeftHeld())
						{
							StartSwing(obj2);
						}
						else
						{
							_anim = null;
							_eul = Wrap(_eul);
						}
						if (_anim != null)
						{
							_anim.Evaluate(_time, out euler, out pos);
							euler *= _intensity.Value;
						}
					}
					else if (!_anim.IsSwing && flag && _time >= _anim.LoopEnd)
					{
						_anim.Evaluate(_anim.LoopEnd, out _bridgeEul, out _bridgePos);
						_bridgeEul = Wrap(_bridgeEul * _intensity.Value);
						_eul = Wrap(_eul);
						_time = _anim.LoopStart;
						_bridge = 0f;
						euler = _bridgeEul;
						pos = _bridgePos;
					}
					else if (_time >= _anim.Duration)
					{
						_anim = null;
						_eul = Wrap(_eul);
					}
					else
					{
						_anim.Evaluate(_time, out euler, out pos);
						euler *= _intensity.Value;
					}
				}
				if (_anim != null && !_anim.IsSwing)
				{
					float num4 = ((_bridge >= 0f) ? 1f : _anim.Envelope(_time));
					float time = Time.time;
					euler += num4 * new Vector3((Mathf.PerlinNoise(time * 0.35f, 0.1f) - 0.5f) * 2f, (Mathf.PerlinNoise(0.3f, time * 0.3f) - 0.5f) * 2.5f, (Mathf.PerlinNoise(time * 0.25f, 7.7f) - 0.5f) * 2f);
				}
			}
			if (_anim == null || (!flag && _bridge < 0f && _time > _anim.Duration - 0.7f))
			{
				Hands.BeginReturn();
			}
			float num5 = ((_anim == null) ? 0.18f : (_anim.IsSwing ? 0.012f : (0.02f + _smoothing.Value * 0.1f)));
			_eul = Vector3.SmoothDamp(_eul, euler, ref _eulVel, num5, float.PositiveInfinity, num);
			_pos = Vector3.SmoothDamp(_pos, pos, ref _posVel, num5, float.PositiveInfinity, num);
			LocalRot = Quaternion.Euler(_eul);
			Vector3 val = Refs.DefaultPos(obj2);
			LocalPos = (Vector3)(_bringCloser.Value ? new Vector3((0f - val.x) * (Hands.OneHanded ? 0.45f : 0.9f) * _pos.x, _pos.y, _pos.z * Stabilizer.TowardFaceScale) : Vector3.zero);
			if (_anim == null && !Hands.Busy && ((Vector3)(ref _eul)).sqrMagnitude < 0.01f && ((Vector3)(ref _eulVel)).sqrMagnitude < 0.01f && ((Vector3)(ref _pos)).sqrMagnitude < 1E-06f && ((Vector3)(ref _posVel)).sqrMagnitude < 1E-06f)
			{
				ResetAll();
			}
		}

		private void StartSwing(object item)
		{
			//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)
			InspectedItem = item;
			Stabilizer.Begin(Refs.LocalCharacter(), item);
			_eul = Wrap(_eul);
			_anim = InspectAnim.Swing;
			_time = 0f;
			_bridge = -1f;
			Active = true;
		}

		private static Vector3 Wrap(Vector3 e)
		{
			//IL_0005: 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_0025: 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)
			return new Vector3(Mathf.DeltaAngle(0f, e.x), Mathf.DeltaAngle(0f, e.y), Mathf.DeltaAngle(0f, e.z));
		}

		private void ResetAll()
		{
			//IL_0021: 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_0027: 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)
			//IL_002d: 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_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: 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_003d: 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_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_0058: 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)
			Hands.Restore();
			Stabilizer.Restore();
			Active = false;
			InspectedItem = null;
			_anim = null;
			_eul = (_eulVel = (_pos = (_posVel = Vector3.zero)));
			_bridge = -1f;
			LocalRot = Quaternion.identity;
			LocalPos = Vector3.zero;
		}

		private InspectAnim PickAnimation(object item)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			string text = _style.Value;
			if (text == "Auto")
			{
				text = ItemStyles.Choose((Component)item, _itemStyles.Value, out var reason);
				Log.LogDebug((object)(((Object)(Component)item).name + ": анимация " + text + " (" + reason + ")"));
			}
			InspectAnim inspectAnim = InspectAnim.ByName(text);
			if (inspectAnim == null)
			{
				int num = InspectAnim.All.Length;
				int num2 = Random.Range(0, num);
				if (num2 == _lastStyle)
				{
					num2 = (num2 + 1 + Random.Range(0, num - 1)) % num;
				}
				_lastStyle = num2;
				inspectAnim = InspectAnim.All[num2];
			}
			return inspectAnim;
		}

		private static bool CanStart(object character, object item)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Invalid comparison between Unknown and I4
			if ((int)Cursor.lockState != 1)
			{
				return false;
			}
			return !ShouldCancel(character, item);
		}

		private static bool ShouldCancel(object character, object item)
		{
			if (Refs.IsUsing(item))
			{
				return true;
			}
			object obj = Refs.Data(character);
			if (obj == null)
			{
				return true;
			}
			if (!Refs.GetBool(Refs.F_isClimbing, obj) && !Refs.GetBool(Refs.F_passedOut, obj) && !Refs.GetBool(Refs.F_fullyPassedOut, obj))
			{
				return Refs.GetBool(Refs.P_dead, obj);
			}
			return true;
		}
	}
	internal static class Stabilizer
	{
		private const float MinOffset = 0.02f;

		private const float TallOffset = 0.15f;

		private static Rigidbody _rig;

		private static Vector3 _savedCom;

		private static Behaviour[] _disabled = (Behaviour[])(object)new Behaviour[0];

		private static readonly List<(Collider, Collider)> _ignored = new List<(Collider, Collider)>();

		private static readonly HashSet<string> _logged = new HashSet<string>();

		private static object _item;

		public static float TowardFaceScale { get; private set; } = 1f;

		public static void Begin(object character, object item)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: 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_0090: 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)
			//IL_013b: 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)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			if (item == null || item == _item)
			{
				return;
			}
			Restore();
			_item = item;
			Rigidbody val = Refs.ItemRig(item);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			List<Behaviour> list = new List<Behaviour>();
			Behaviour[] components = ((Component)item).GetComponents<Behaviour>();
			foreach (Behaviour val2 in components)
			{
				if ((Object)(object)val2 != (Object)null && val2.enabled && ((object)val2).GetType().Name == "CenterOfMass")
				{
					list.Add(val2);
				}
			}
			Vector3 centerOfMass = val.centerOfMass;
			string text = ((Object)(Component)item).name.Replace("(Clone)", "");
			if (_logged.Add(text))
			{
				Plugin.Info($"{text}: центр масс {centerOfMass} ({((Vector3)(ref centerOfMass)).magnitude:0.000} м от точки хвата), " + "CenterOfMass: " + ((list.Count > 0) ? "есть" : "нет"));
			}
			TowardFaceScale = ((((Vector3)(ref centerOfMass)).magnitude >= 0.15f) ? 0.3f : 1f);
			IgnoreOwnBody(character, item);
			if (list.Count != 0 || !(((Vector3)(ref centerOfMass)).magnitude < 0.02f))
			{
				_rig = val;
				_savedCom = centerOfMass;
				_disabled = list.ToArray();
				components = _disabled;
				for (int i = 0; i < components.Length; i++)
				{
					components[i].enabled = false;
				}
				val.centerOfMass = Vector3.zero;
			}
		}

		private static void IgnoreOwnBody(object character, object item)
		{
			//IL_0005: 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)
			if (character == null)
			{
				return;
			}
			Collider[] componentsInChildren = ((Component)item).GetComponentsInChildren<Collider>();
			Collider[] componentsInChildren2 = ((Component)character).GetComponentsInChildren<Collider>();
			Collider[] array = componentsInChildren;
			foreach (Collider val in array)
			{
				if ((Object)(object)val == (Object)null || !val.enabled || val.isTrigger)
				{
					continue;
				}
				Collider[] array2 = componentsInChildren2;
				foreach (Collider val2 in array2)
				{
					if (!((Object)(object)val2 == (Object)null) && !val2.isTrigger && !Physics.GetIgnoreCollision(val, val2))
					{
						Physics.IgnoreCollision(val, val2, true);
						_ignored.Add((val, val2));
					}
				}
			}
		}

		public static void Restore()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_rig != (Object)null)
			{
				_rig.centerOfMass = _savedCom;
			}
			Behaviour[] disabled = _disabled;
			foreach (Behaviour val in disabled)
			{
				if ((Object)(object)val != (Object)null)
				{
					val.enabled = true;
				}
			}
			foreach (var (val2, val3) in _ignored)
			{
				if ((Object)(object)val2 != (Object)null && (Object)(object)val3 != (Object)null)
				{
					Physics.IgnoreCollision(val2, val3, false);
				}
			}
			_ignored.Clear();
			_rig = null;
			_item = null;
			_disabled = (Behaviour[])(object)new Behaviour[0];
			TowardFaceScale = 1f;
		}
	}
	internal sealed class InspectAnim
	{
		internal struct Key
		{
			public float t;

			public Vector3 euler;

			public Vector3 pos;

			public Key(float t, float pitch, float yaw, float roll, float cx, float up, float fwd)
			{
				//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_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)
				this.t = t;
				euler = new Vector3(pitch, yaw, roll);
				pos = new Vector3(cx, up, fwd);
			}
		}

		private readonly Key[] _keys;

		public readonly string Name;

		public readonly float LoopStart;

		public readonly float LoopEnd;

		public bool IsSwing;

		private static readonly InspectAnim Classic = new InspectAnim("Classic", 2, new Key(0f, 0f, 0f, 0f, 0f, 0f, 0f), new Key(0.5f, -8f, 10f, 10f, 0.8f, 0.07f, -0.07f), new Key(1.2f, -12f, -38f, -78f, 1f, 0.1f, -0.12f), new Key(1.9f, -15f, -40f, -84f, 1f, 0.1f, -0.12f), new Key(2.6f, -48f, -12f, -20f, 1f, 0.12f, -0.12f), new Key(3.2f, -50f, -10f, -16f, 1f, 0.12f, -0.12f), new Key(4f, 8f, 38f, 84f, 1f, 0.1f, -0.12f), new Key(4.7f, 10f, 40f, 88f, 1f, 0.1f, -0.12f), new Key(5.35f, 35f, 12f, 25f, 1f, 0.09f, -0.11f), new Key(5.9f, 32f, 10f, 22f, 1f, 0.09f, -0.11f), new Key(6.6f, 0f, 0f, 0f, 0f, 0f, 0f));

		private static readonly InspectAnim Flip = new InspectAnim("Flip", 1, new Key(0f, 0f, 0f, 0f, 0f, 0f, 0f), new Key(0.5f, -10f, -10f, -15f, 1f, 0.09f, -0.1f), new Key(1.3f, -30f, -18f, -90f, 1f, 0.11f, -0.12f), new Key(2f, -32f, -20f, -95f, 1f, 0.11f, -0.12f), new Key(2.8f, -8f, 36f, 55f, 1f, 0.1f, -0.12f), new Key(3.5f, -6f, 38f, 60f, 1f, 0.1f, -0.12f), new Key(4.3f, 38f, 10f, 10f, 1f, 0.09f, -0.11f), new Key(4.9f, 35f, 8f, 8f, 1f, 0.09f, -0.11f), new Key(5.5f, 0f, 0f, 0f, 0f, 0f, 0f));

		private static readonly InspectAnim Toss = new InspectAnim("Toss", 1, new Key(0f, 0f, 0f, 0f, 0f, 0f, 0f), new Key(0.7f, -36f, 0f, 0f, 1f, 0.11f, -0.12f), new Key(1.4f, -38f, 4f, 3f, 1f, 0.11f, -0.12f), new Key(2.2f, -16f, -32f, -80f, 1f, 0.11f, -0.12f), new Key(2.9f, -18f, -34f, -84f, 1f, 0.11f, -0.12f), new Key(3.8f, 10f, 32f, 80f, 1f, 0.11f, -0.12f), new Key(4.5f, 12f, 34f, 84f, 1f, 0.11f, -0.12f), new Key(5.2f, 30f, 0f, 0f, 1f, 0.1f, -0.11f), new Key(5.7f, 28f, 2f, 2f, 1f, 0.1f, -0.11f), new Key(6.4f, 0f, 0f, 0f, 0f, 0f, 0f));

		private static readonly InspectAnim Gentle = new InspectAnim("Gentle", 1, new Key(0f, 0f, 0f, 0f, 0f, 0f, 0f), new Key(0.9f, -8f, -30f, -35f, 0.8f, 0.06f, -0.07f), new Key(1.8f, -10f, -32f, -38f, 0.8f, 0.06f, -0.07f), new Key(2.8f, -35f, -8f, -10f, 0.8f, 0.07f, -0.07f), new Key(3.5f, -33f, -6f, -8f, 0.8f, 0.07f, -0.07f), new Key(4.6f, 6f, 22f, 88f, 0.8f, 0.06f, -0.07f), new Key(5.8f, 8f, 24f, 92f, 0.8f, 0.06f, -0.07f), new Key(6.8f, 0f, 0f, 0f, 0f, 0f, 0f));

		private static readonly InspectAnim Blade = new InspectAnim("Blade", 1, new Key(0f, 0f, 0f, 0f, 0f, 0f, 0f), new Key(0.9f, 0f, -30f, -35f, 0.6f, 0.04f, 0.03f), new Key(1.8f, -2f, -32f, -38f, 0.6f, 0.04f, 0.03f), new Key(2.8f, -15f, -8f, -10f, 0.6f, 0.05f, 0.03f), new Key(3.5f, -14f, -6f, -8f, 0.6f, 0.05f, 0.03f), new Key(4.4f, -30f, 20f, 88f, 0.8f, 0.07f, -0.08f), new Key(5.1f, -72f, 18f, 90f, 0.8f, 0.08f, -0.09f), new Key(6.1f, -75f, 16f, 92f, 0.8f, 0.08f, -0.09f), new Key(7.1f, 0f, 0f, 0f, 0f, 0f, 0f));

		private static readonly InspectAnim Heavy = new InspectAnim("Heavy", 1, new Key(0f, 0f, 0f, 0f, 0f, 0f, 0f), new Key(1f, -8f, -16f, -18f, 0.5f, 0.04f, -0.04f), new Key(2f, -10f, -18f, -20f, 0.5f, 0.04f, -0.04f), new Key(3f, -20f, 0f, 0f, 0.5f, 0.05f, -0.04f), new Key(3.7f, -18f, 2f, 2f, 0.5f, 0.05f, -0.04f), new Key(4.7f, 6f, 16f, 18f, 0.5f, 0.04f, -0.04f), new Key(5.5f, 8f, 18f, 20f, 0.5f, 0.04f, -0.04f), new Key(6.3f, 0f, 0f, 0f, 0f, 0f, 0f));

		private static readonly InspectAnim Lift = new InspectAnim("Lift", 1, new Key(0f, 0f, 0f, 0f, 0f, 0f, 0f), new Key(0.9f, -12f, 0f, 0f, 1f, 0.14f, -0.14f), new Key(1.8f, -14f, 4f, 2f, 1f, 0.15f, -0.15f), new Key(2.6f, -10f, -22f, -30f, 1f, 0.14f, -0.14f), new Key(3.3f, -12f, -24f, -34f, 1f, 0.14f, -0.14f), new Key(4.2f, -10f, 22f, 30f, 1f, 0.14f, -0.14f), new Key(4.9f, -12f, 24f, 34f, 1f, 0.14f, -0.14f), new Key(5.6f, 15f, 0f, 0f, 1f, 0.11f, -0.12f), new Key(6.1f, 14f, 0f, 0f, 1f, 0.11f, -0.12f), new Key(6.8f, 0f, 0f, 0f, 0f, 0f, 0f));

		internal static readonly InspectAnim[] All = new InspectAnim[7] { Classic, Flip, Toss, Gentle, Lift, Heavy, Blade };

		internal static readonly InspectAnim Swing = new InspectAnim("Swing", 1, new Key(0f, 0f, 0f, 0f, 0f, 0f, 0f), new Key(0.18f, -10f, 45f, 55f, -0.6f, 0.03f, 0f), new Key(0.3f, -5f, 0f, 70f, 0.8f, 0.01f, 0.14f), new Key(0.4f, 0f, -40f, 70f, 1.7f, 0f, 0.08f), new Key(0.75f, 0f, 0f, 0f, 0f, 0f, 0f))
		{
			IsSwing = true
		};

		public float Duration => _keys[_keys.Length - 1].t;

		public InspectAnim(string name, int loopFrom, params Key[] keys)
		{
			Name = name;
			_keys = keys;
			LoopStart = keys[loopFrom].t;
			LoopEnd = keys[^2].t;
		}

		public void Evaluate(float t, out Vector3 euler, out Vector3 pos)
		{
			//IL_0061: 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_006d: 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_0079: 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_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			int i;
			for (i = 0; i < _keys.Length - 2 && t > _keys[i + 1].t; i++)
			{
			}
			Key key = _keys[i];
			Key key2 = _keys[i + 1];
			float num = Smooth(Mathf.InverseLerp(key.t, key2.t, t));
			euler = Vector3.LerpUnclamped(key.euler, key2.euler, num);
			pos = Vector3.LerpUnclamped(key.pos, key2.pos, num);
		}

		public float Envelope(float t)
		{
			return Mathf.Clamp01(Mathf.Min(t / 0.5f, (Duration - t) / 0.6f));
		}

		public static float Smooth(float x)
		{
			x = Mathf.Clamp01(x);
			return x * x * x * (x * (x * 6f - 15f) + 10f);
		}

		internal static InspectAnim ByName(string name)
		{
			InspectAnim[] all = All;
			foreach (InspectAnim inspectAnim in all)
			{
				if (string.Equals(inspectAnim.Name, name, StringComparison.OrdinalIgnoreCase))
				{
					return inspectAnim;
				}
			}
			return null;
		}
	}
	internal static class ItemStyles
	{
		private static readonly (string[] words, string style)[] Rules = new(string[], string)[10]
		{
			(new string[3] { "amulet", "rescuehook", "hook" }, "Gentle"),
			(new string[2] { "idol", "statue" }, "Lift"),
			(new string[7] { "energy", "drink", "soda", "bottle", "flask", "potion", "jar" }, "Toss"),
			(new string[6] { "antizooka", "shovel", "chain", "pan", "cannon", "launcher" }, "Heavy"),
			(new string[5] { "dagger", "ritual", "knife", "sword", "blade" }, "Blade"),
			(new string[6] { "frog", "bingbongplush", "plush", "toy", "chicken", "bird" }, "Lift"),
			(new string[11]
			{
				"guidebook", "book", "map", "scroll", "passport", "compass", "frisbee", "cure", "bandage", "clothes",
				"card"
			}, "Flip"),
			(new string[25]
			{
				"basketball", "ball", "coconut", "egg", "apple", "berry", "mushroom", "shroom", "marshmallow", "nut",
				"stone", "rock", "shell", "seed", "granola", "bar", "banana", "cactus", "bingbong", "honey",
				"pepper", "candy", "cookie", "dart", "bean"
			}, "Toss"),
			(new string[9] { "lantern", "rope", "parasol", "umbrella", "backpack", "kiln", "tent", "balloon", "ladder" }, "Gentle"),
			(new string[9] { "bugle", "binocular", "flare", "torch", "axe", "pick", "stick", "piton", "sling" }, "Classic")
		};

		private static readonly Dictionary<string, string> KnownComponents = new Dictionary<string, string>
		{
			{ "Guidebook", "guidebook" },
			{ "Lantern", "lantern" },
			{ "Flare", "flare" },
			{ "Frisbee", "frisbee" },
			{ "Parasol", "parasol" },
			{ "Basketball", "basketball" },
			{ "BingBong", "bingbong" },
			{ "Rope", "rope" },
			{ "BugleSFX", "bugle" },
			{ "CompassPointer", "compass" },
			{ "CactusBall", "cactus" },
			{ "Snowball", "stone" }
		};

		private static readonly string[] BuiltInOneHand = new string[7] { "bean", "berry", "mushroom", "shroom", "egg", "nut", "seed" };

		private static readonly string[] BuiltInTwoHands = new string[3] { "cure", "panacea", "remedy" };

		public static string Choose(Component item, string userRules, out string reason)
		{
			//IL_0109: 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_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: 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)
			string text = Describe(item);
			string[] array = (userRules ?? "").Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string[] array2 = array[i].Split('=');
				if (array2.Length == 2)
				{
					string text2 = array2[0].Trim().ToLowerInvariant();
					string name = array2[1].Trim();
					if (text2.Length > 0 && text.Contains(text2) && InspectAnim.ByName(name) != null)
					{
						reason = "правило '" + text2 + "' из конфига";
						return InspectAnim.ByName(name).Name;
					}
				}
			}
			(string[], string)[] rules = Rules;
			for (int i = 0; i < rules.Length; i++)
			{
				(string[], string) tuple = rules[i];
				string[] item2 = tuple.Item1;
				string item3 = tuple.Item2;
				array = item2;
				foreach (string text3 in array)
				{
					if (text.Contains(text3))
					{
						reason = "название содержит '" + text3 + "'";
						return item3;
					}
				}
			}
			if (TryGetSize(item, out var size))
			{
				float num = Mathf.Max(size.x, Mathf.Max(size.y, size.z));
				float num2 = Mathf.Min(size.x, Mathf.Min(size.y, size.z));
				if (num > 0.7f)
				{
					reason = $"большой ({num:0.00} м)";
					return "Gentle";
				}
				if (num2 < num * 0.3f)
				{
					reason = "плоский/вытянутый";
					if (!(num < 0.35f))
					{
						return "Classic";
					}
					return "Flip";
				}
				if (num < 0.25f)
				{
					reason = $"маленький ({num:0.00} м)";
					return "Toss";
				}
			}
			reason = "по умолчанию";
			return "Classic";
		}

		public static bool IsSwingItem(Component item, string list)
		{
			if (Refs.HasPrimaryAction(item))
			{
				return false;
			}
			string text = Describe(item);
			string[] array = (list ?? "").Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string text2 = array[i].Trim().ToLowerInvariant();
				if (text2.Length > 0 && text.Contains(text2))
				{
					return true;
				}
			}
			return false;
		}

		public static bool WantsOneHand(Component item, string list, bool small)
		{
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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 (Refs.RightHandOnly(item))
			{
				return false;
			}
			string text = Describe(item);
			string[] builtInTwoHands = BuiltInTwoHands;
			foreach (string value in builtInTwoHands)
			{
				if (text.Contains(value))
				{
					return false;
				}
			}
			builtInTwoHands = BuiltInOneHand;
			foreach (string value2 in builtInTwoHands)
			{
				if (text.Contains(value2))
				{
					return true;
				}
			}
			builtInTwoHands = (list ?? "").Split(',');
			for (int i = 0; i < builtInTwoHands.Length; i++)
			{
				string text2 = builtInTwoHands[i].Trim().ToLowerInvariant();
				if (text2.Length > 0 && text.Contains(text2))
				{
					return true;
				}
			}
			if (small && TryGetSize(item, out var size))
			{
				return Mathf.Max(size.x, Mathf.Max(size.y, size.z)) < 0.3f;
			}
			return false;
		}

		private static string Describe(Component item)
		{
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(((Object)item.gameObject).name).Append(' ');
			try
			{
				object obj = AccessTools.Field(((object)item).GetType(), "UIData")?.GetValue(item);
				object obj2 = ((obj == null) ? null : AccessTools.Field(obj.GetType(), "itemName")?.GetValue(obj));
				if (obj2 != null)
				{
					stringBuilder.Append(obj2).Append(' ');
				}
			}
			catch
			{
			}
			Component[] components = item.GetComponents<Component>();
			foreach (Component val in components)
			{
				if ((Object)(object)val != (Object)null && KnownComponents.TryGetValue(((object)val).GetType().Name, out var value))
				{
					stringBuilder.Append(value).Append(' ');
				}
			}
			return stringBuilder.ToString().Replace("(Clone)", "").Replace("_", "")
				.ToLowerInvariant();
		}

		private static bool TryGetSize(Component item, out Vector3 size)
		{
			//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_000f: 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_00a2: 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_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)
			size = Vector3.zero;
			bool flag = false;
			Bounds val = default(Bounds);
			Renderer[] componentsInChildren = item.GetComponentsInChildren<Renderer>();
			foreach (Renderer val2 in componentsInChildren)
			{
				if ((Object)(object)val2 == (Object)null || !val2.enabled || !((Component)val2).gameObject.activeInHierarchy)
				{
					continue;
				}
				string name = ((object)val2).GetType().Name;
				if (!(name != "MeshRenderer") || !(name != "SkinnedMeshRenderer"))
				{
					if (!flag)
					{
						val = val2.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref val)).Encapsulate(val2.bounds);
					}
				}
			}
			if (flag)
			{
				size = ((Bounds)(ref val)).size;
			}
			return flag;
		}
	}
	internal static class Hands
	{
		private enum State
		{
			None,
			Released,
			Returning
		}

		private static State _state;

		private static object _character;

		private static object _item;

		private static float _ikL = 1f;

		private static float _retTime;

		public static bool Busy => _state != State.None;

		public static bool OneHanded => _state != State.None;

		public static float LeftIK => _ikL;

		public static bool Controls(object character)
		{
			if (_state != State.None)
			{
				return character == _character;
			}
			return false;
		}

		public static void Begin(object character, object item, bool oneHand)
		{
			if (_state != State.None && item != _item)
			{
				Restore();
			}
			if (!oneHand)
			{
				return;
			}
			if (_state == State.None)
			{
				Rigidbody val = Refs.ItemRig(item);
				if ((Object)(object)val == (Object)null || !RemoveJoints(Refs.HandRig(character, "Hand_L"), val))
				{
					return;
				}
				_character = character;
				_item = item;
				_ikL = 1f;
			}
			_state = State.Released;
		}

		public static void BeginReturn()
		{
			if (_state == State.Released)
			{
				_state = State.Returning;
				_retTime = 0f;
			}
		}

		public static void Tick(float dt)
		{
			if (_state == State.None)
			{
				return;
			}
			if (Refs.CurrentItem(_character) != _item)
			{
				Restore();
				return;
			}
			if (_state == State.Released)
			{
				_ikL = Mathf.MoveTowards(_ikL, 0f, dt / 0.4f);
				return;
			}
			_retTime += dt;
			_ikL = Mathf.MoveTowards(_ikL, 1f, dt / 0.5f);
			if (_ikL >= 1f && (LeftHandAtGrip(0.05f) || (_retTime > 1.5f && LeftHandAtGrip(0.15f)) || _retTime > 3f))
			{
				Restore();
			}
		}

		public static void Restore()
		{
			if (_state == State.None)
			{
				return;
			}
			_state = State.None;
			_ikL = 1f;
			object character = _character;
			object item = _item;
			_character = (_item = null);
			try
			{
				if (character != null && item != null && Refs.CurrentItem(character) == item)
				{
					Rigidbody val = Refs.ItemRig(item);
					Rigidbody val2 = Refs.HandRig(character, "Hand_L");
					if ((Object)(object)val != (Object)null && (Object)(object)val2 != (Object)null)
					{
						((Joint)((Component)val2).gameObject.AddComponent<FixedJoint>()).connectedBody = val;
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Error("Не удалось вернуть левую руку на предмет: " + ex);
			}
		}

		private static bool LeftHandAtGrip(float maxDist)
		{
			//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_002c: 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_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)
			Rigidbody val = Refs.HandRig(_character, "Hand_L");
			if ((Object)(object)val == (Object)null)
			{
				return true;
			}
			Vector3 val2 = Refs.LeftGripWorld(_character, _item);
			Vector3 val3 = val.position - val2;
			return ((Vector3)(ref val3)).sqrMagnitude <= maxDist * maxDist;
		}

		private static bool RemoveJoints(Rigidbody hand, Rigidbody itemRig)
		{
			if ((Object)(object)hand == (Object)null)
			{
				return false;
			}
			bool result = false;
			FixedJoint[] components = ((Component)hand).GetComponents<FixedJoint>();
			foreach (FixedJoint val in components)
			{
				if ((Object)(object)val != (Object)null && (Object)(object)((Joint)val).connectedBody == (Object)(object)itemRig)
				{
					Object.DestroyImmediate((Object)(object)val);
					result = true;
				}
			}
			return result;
		}
	}
	internal static class InspectPrompt
	{
		private static GameObject _row;

		private static GameObject _spacer;

		private static GameObject _throwRow;

		private static GameObject _swingRow;

		private static readonly List<GameObject> _keyIcons = new List<GameObject>();

		private static Component _owner;

		private static bool _failed;

		public static void RefreshKey()
		{
			string text = InputReader.IconTag(Plugin.KeyName);
			foreach (GameObject keyIcon in _keyIcons)
			{
				if ((Object)(object)keyIcon != (Object)null)
				{
					SetText(keyIcon, text);
				}
			}
		}

		public static void Update(Component gui)
		{
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Expected O, but got Unknown
			if (_failed)
			{
				return;
			}
			object field = Refs.GetField(gui, "itemPromptDrop");
			object obj = ((field is Component) ? field : null);
			GameObject val = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if ((Object)(object)_row == (Object)null || _owner != gui)
			{
				Create(gui, val);
			}
			if ((Object)(object)_row == (Object)null)
			{
				return;
			}
			bool flag = Plugin.ShowPrompt.Value && HasItem();
			if (_row.activeSelf != flag)
			{
				_row.SetActive(flag);
			}
			if ((Object)(object)_swingRow != (Object)null)
			{
				object obj2 = Refs.LocalCharacter();
				object obj3 = ((obj2 != null) ? Refs.CurrentItem(obj2) : null);
				bool flag2 = flag && obj3 != null && ItemStyles.IsSwingItem((Component)obj3, Plugin.SwingItems.Value);
				if (_swingRow.activeSelf != flag2)
				{
					_swingRow.SetActive(flag2);
				}
			}
			if ((Object)(object)_spacer != (Object)null)
			{
				bool flag3 = flag && (Object)(object)_throwRow != (Object)null && _throwRow.activeInHierarchy;
				if (_spacer.activeSelf != flag3)
				{
					_spacer.SetActive(flag3);
				}
			}
		}

		private static bool HasItem()
		{
			object obj = Refs.LocalCharacter();
			if (obj != null)
			{
				return Refs.CurrentItem(obj) != null;
			}
			return false;
		}

		private static void Create(Component gui, GameObject drop)
		{
			_owner = gui;
			Type type = Refs.GameType("InputIcon");
			GameObject val = drop;
			if ((Object)(object)drop.GetComponentInChildren(type, true) == (Object)null && (Object)(object)drop.transform.parent != (Object)null && ((Component)drop.transform.parent).GetComponentsInChildren(type, true).Length == 1)
			{
				val = ((Component)drop.transform.parent).gameObject;
			}
			_row = Object.Instantiate<GameObject>(val, val.transform.parent);
			((Object)_row).name = "ItemInspectPrompt";
			_row.transform.SetAsLastSibling();
			object field = Refs.GetField(gui, "itemPromptThrow");
			object obj = ((field is Component) ? field : null);
			_throwRow = ((obj != null) ? ((Component)obj).gameObject : null);
			if ((Object)(object)_throwRow != (Object)null && (Object)(object)val != (Object)(object)drop && (Object)(object)_throwRow.transform.parent != (Object)null && (Object)(object)_throwRow.transform.parent.parent == (Object)(object)val.transform.parent)
			{
				_throwRow = ((Component)_throwRow.transform.parent).gameObject;
			}
			MakeSpacer(val);
			Component[] componentsInChildren = _row.GetComponentsInChildren<Component>(true);
			foreach (Component val2 in componentsInChildren)
			{
				if (!((Object)(object)val2 == (Object)null) && ((object)val2).GetType().Name == "LocalizedText")
				{
					Object.DestroyImmediate((Object)(object)val2);
				}
			}
			string text = InputReader.IconTag(Plugin.KeyName);
			_keyIcons.Clear();
			componentsInChildren = _row.GetComponentsInChildren(type, true);
			foreach (Component val3 in componentsInChildren)
			{
				object? obj2 = AccessTools.Field(type, "hold")?.GetValue(val3);
				GameObject val4 = (GameObject)((obj2 is GameObject) ? obj2 : null);
				if ((Object)(object)val4 != (Object)null)
				{
					val4.SetActive(false);
				}
				GameObject gameObject = val3.gameObject;
				Object.DestroyImmediate((Object)(object)val3);
				SetText(gameObject, text);
				_keyIcons.Add(gameObject);
			}
			componentsInChildren = _row.GetComponentsInChildren<Component>(true);
			foreach (Component val5 in componentsInChildren)
			{
				if (!((Object)(object)val5 == (Object)null) && IsText(val5))
				{
					string text2 = GetText(val5);
					if (text2 == null || !text2.Contains("<sprite"))
					{
						SetText(val5.gameObject, Plugin.PromptText.Value);
						break;
					}
				}
			}
			_swingRow = Object.Instantiate<GameObject>(_row, _row.transform.parent);
			((Object)_swingRow).name = "ItemSwingPrompt";
			_swingRow.transform.SetAsLastSibling();
			if ((Object)(object)_swingRow != (Object)null)
			{
				string value = MouseTag();
				bool flag = false;
				componentsInChildren = _swingRow.GetComponentsInChildren<Component>(true);
				foreach (Component val6 in componentsInChildren)
				{
					if (!((Object)(object)val6 == (Object)null) && IsText(val6))
					{
						string text3 = GetText(val6);
						if (text3 != null && text3.Contains("<sprite"))
						{
							((object)val6).GetType().GetProperty("text", typeof(string)).SetValue(val6, value);
						}
						else if (!flag)
						{
							((object)val6).GetType().GetProperty("text", typeof(string)).SetValue(val6, Plugin.SwingPromptText.Value);
							flag = true;
						}
					}
				}
				_swingRow.SetActive(false);
			}
			Plugin.Info("Подсказка «осмотр» добавлена в интерфейс");
		}

		private static void MakeSpacer(GameObject source)
		{
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Expected O, but got Unknown
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0164: 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)
			Transform parent = source.transform.parent;
			RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null);
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			Transform transform = source.transform;
			Transform obj = ((transform is RectTransform) ? transform : null);
			float num;
			if (obj == null)
			{
				num = 20f;
			}
			else
			{
				Rect rect = ((RectTransform)obj).rect;
				num = ((Rect)(ref rect)).height;
			}
			float num2 = num;
			if (num2 <= 1f)
			{
				num2 = 20f;
			}
			bool flag = false;
			Component[] components = ((Component)val).GetComponents<Component>();
			foreach (Component val2 in components)
			{
				if ((Object)(object)val2 != (Object)null && ((object)val2).GetType().Name.Contains("LayoutGroup"))
				{
					flag = true;
				}
			}
			if (flag)
			{
				_spacer = new GameObject("ItemInspectPromptSpacer", new Type[1] { typeof(RectTransform) });
				_spacer.transform.SetParent((Transform)(object)val, false);
				_spacer.transform.SetSiblingIndex(_row.transform.GetSiblingIndex());
				Type type = Type.GetType("UnityEngine.UI.LayoutElement, UnityEngine.UI");
				if (type != null)
				{
					Component obj2 = _spacer.AddComponent(type);
					type.GetProperty("minHeight")?.SetValue(obj2, num2 * 0.6f);
					type.GetProperty("preferredHeight")?.SetValue(obj2, num2 * 0.6f);
				}
				((RectTransform)_spacer.transform).sizeDelta = new Vector2(1f, num2 * 0.6f);
			}
			else
			{
				Transform transform2 = _row.transform;
				RectTransform val3 = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
				if (val3 != null)
				{
					val3.anchoredPosition += new Vector2(0f, (0f - num2) * 0.6f);
				}
			}
		}

		private static string MouseTag()
		{
			return InputReader.SpriteTag("inputPathToSpriteTagMouse", "leftButton") ?? "[ЛКМ]";
		}

		private static bool IsText(Component c)
		{
			if (((object)c).GetType().GetProperty("text", typeof(string)) != null)
			{
				return ((object)c).GetType().Name.Contains("Text");
			}
			return false;
		}

		private static string GetText(Component c)
		{
			return ((object)c).GetType().GetProperty("text", typeof(string))?.GetValue(c) as string;
		}

		private static void SetText(GameObject go, string text)
		{
			Component[] components = go.GetComponents<Component>();
			foreach (Component val in components)
			{
				if ((Object)(object)val != (Object)null && IsText(val))
				{
					((object)val).GetType().GetProperty("text", typeof(string)).SetValue(val, text);
					break;
				}
			}
		}

		public static void Fail(Exception e)
		{
			if (!_failed)
			{
				_failed = true;
				if ((Object)(object)_row != (Object)null)
				{
					Object.Destroy((Object)(object)_row);
				}
				Plugin.Error("Подсказка «осмотр» отключена из-за ошибки: " + e);
			}
		}
	}
	internal static class Patches
	{
		[HarmonyPatch]
		internal static class HoldForward
		{
			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(Refs.GameType("CharacterItems"), "GetItemHoldForward", (Type[])null, (Type[])null);
			}

			private static void Postfix(object __instance, ref Vector3 __result)
			{
				//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_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)
				try
				{
					if (AppliesTo(__instance, out var character))
					{
						__result = TargetRotation(character) * Vector3.forward;
					}
				}
				catch (Exception e)
				{
					Fail(e);
				}
			}
		}

		[HarmonyPatch]
		internal static class HoldUp
		{
			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(Refs.GameType("CharacterItems"), "GetItemHoldUp", (Type[])null, (Type[])null);
			}

			private static void Postfix(object __instance, ref Vector3 __result)
			{
				//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_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)
				try
				{
					if (AppliesTo(__instance, out var character))
					{
						__result = TargetRotation(character) * Vector3.up;
					}
				}
				catch (Exception e)
				{
					Fail(e);
				}
			}
		}

		[HarmonyPatch]
		internal static class LeftHandIK
		{
			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(Refs.GameType("CharacterAnimations"), "HandleIK", (Type[])null, (Type[])null);
			}

			private static void Postfix(object __instance)
			{
				try
				{
					if (Hands.Busy)
					{
						object field = Refs.GetField(__instance, "character");
						if (Hands.Controls(field))
						{
							Refs.ScaleLeftIKWeight(field, Hands.LeftIK);
						}
					}
				}
				catch (Exception e)
				{
					Fail(e);
				}
			}
		}

		[HarmonyPatch]
		internal static class BeforeUnattach
		{
			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(Refs.GameType("CharacterItems"), "UnAttachItem", (Type[])null, (Type[])null);
			}

			private static void Prefix(object __instance)
			{
				try
				{
					if (Hands.Controls(Refs.GetField(__instance, "character")))
					{
						Hands.Restore();
					}
				}
				catch (Exception e)
				{
					Fail(e);
				}
			}
		}

		[HarmonyPatch]
		internal static class ItemPrompts
		{
			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(Refs.GameType("GUIManager"), "UpdateItemPrompts", (Type[])null, (Type[])null);
			}

			private static void Postfix(object __instance)
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_000b: Expected O, but got Unknown
				try
				{
					InspectPrompt.Update((Component)__instance);
				}
				catch (Exception e)
				{
					InspectPrompt.Fail(e);
				}
			}
		}

		[HarmonyPatch]
		internal static class AnimationItemTransform
		{
			private static MethodBase TargetMethod()
			{
				return AccessTools.Method(Refs.GameType("CharacterRagdoll"), "SaveAdditionalTransformPositions", (Type[])null, (Type[])null);
			}

			private static void Postfix(object __instance)
			{
				try
				{
					Apply(__instance);
				}
				catch (Exception e)
				{
					Fail(e);
				}
			}

			private static void Apply(object __instance)
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				//IL_0028: Expected O, but got Unknown
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Expected O, but got Unknown
				//IL_004e: 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_005e: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: 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)
				if (AppliesTo(__instance, out var character))
				{
					object value = Refs.F_refs.GetValue(character);
					Transform val = (Transform)Refs.F_animationItemTransform.GetValue(value);
					Transform val2 = (Transform)Refs.F_animationLookTransform.GetValue(value);
					if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null))
					{
						val.position += val2.TransformVector(Plugin.LocalPos);
						val.rotation *= Plugin.LocalRot;
					}
				}
			}
		}

		private static bool _failed;

		internal static void Fail(Exception e)
		{
			Plugin.Active = false;
			if (!_failed)
			{
				_failed = true;
				Plugin.Error(string.Format("{0}: ошибка в патче (дальнейшие не логируются):\n{1}", "Item Inspect", e));
			}
		}

		private static bool AppliesTo(object characterItemsOrRagdoll, out object character)
		{
			character = null;
			if (!Plugin.Active || characterItemsOrRagdoll == null)
			{
				return false;
			}
			character = Refs.GetField(characterItemsOrRagdoll, "character");
			if (character == null || character != Refs.LocalCharacter())
			{
				return false;
			}
			return Refs.CurrentItem(character) == Plugin.InspectedItem;
		}

		private static Quaternion TargetRotation(object character)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0037: 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_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: 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_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)
			object obj = Refs.Data(character);
			Vector3 val = (Vector3)Refs.F_lookDirection.GetValue(obj);
			Vector3 val2 = (Vector3)Refs.F_lookDirectionUp.GetValue(obj);
			if (((Vector3)(ref val)).sqrMagnitude < 1E-06f)
			{
				val = Vector3.forward;
			}
			if (((Vector3)(ref val2)).sqrMagnitude < 1E-06f)
			{
				val2 = Vector3.up;
			}
			return Quaternion.LookRotation(val, val2) * Plugin.LocalRot;
		}
	}
	internal static class Refs
	{
		internal sealed class Member
		{
			private readonly FieldInfo _f;

			private readonly PropertyInfo _p;

			public Member(FieldInfo f, PropertyInfo p)
			{
				_f = f;
				_p = p;
			}

			public object GetValue(object obj)
			{
				if (!(_f != null))
				{
					return _p.GetValue(obj);
				}
				return _f.GetValue(obj);
			}
		}

		internal static Member F_localCharacter;

		internal static Member F_data;

		internal static Member F_refs;

		internal static Member F_currentItem;

		internal static Member F_lookDirection;

		internal static Member F_lookDirectionUp;

		internal static Member F_isClimbing;

		internal static Member F_passedOut;

		internal static Member F_fullyPassedOut;

		internal static Member P_dead;

		internal static Member P_usingPrimary;

		internal static Member P_usingSecondary;

		internal static Member F_animationItemTransform;

		internal static Member F_animationLookTransform;

		internal static Member F_defaultPos;

		private const BindingFlags All = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic;

		internal static Assembly Game;

		private static MethodInfo _getBodypartRig;

		private static MethodInfo _posLeftWorld;

		private static Member _items;

		private static Member _ikLeft;

		private static Member _rig;

		private static Member _rightHandOnly;

		private static PropertyInfo _weight;

		private static Type _bodypartType;

		private static MethodInfo _canUsePrimary;

		internal static Type GameType(string name)
		{
			if (Game == null)
			{
				Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
				foreach (Assembly assembly in assemblies)
				{
					if (assembly.GetName().Name == "Assembly-CSharp")
					{
						Game = assembly;
						break;
					}
				}
			}
			if (Game == null)
			{
				throw new Exception("Assembly-CSharp не найдена");
			}
			return Game.GetType(name, throwOnError: false) ?? throw new Exception("Тип " + name + " не найден в Assembly-CSharp");
		}

		internal static Member Get(Type t, string name)
		{
			Type type = t;
			while (type != null)
			{
				FieldInfo field = type.GetField(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (field != null)
				{
					return new Member(field, null);
				}
				PropertyInfo property = type.GetProperty(name, BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
				if (property != null && property.GetGetMethod(nonPublic: true) != null)
				{
					return new Member(null, property);
				}
				type = type.BaseType;
			}
			throw new Exception(t.Name + "." + name + " не найдено (игра обновилась?)");
		}

		internal static void Init()
		{
			Type type = GameType("Character");
			Type t = GameType("CharacterData");
			Type t2 = type.GetNestedType("CharacterRefs", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic) ?? throw new Exception("Character.CharacterRefs не найден");
			Type t3 = GameType("Item");
			F_localCharacter = Get(type, "localCharacter");
			F_data = Get(type, "data");
			F_refs = Get(type, "refs");
			F_currentItem = Get(t, "currentItem");
			F_lookDirection = Get(t, "lookDirection");
			F_lookDirectionUp = Get(t, "lookDirection_Up");
			F_isClimbing = Get(t, "isClimbing");
			F_passedOut = Get(t, "passedOut");
			F_fullyPassedOut = Get(t, "fullyPassedOut");
			P_dead = Get(t, "dead");
			F_animationItemTransform = Get(t2, "animationItemTransform");
			F_animationLookTransform = Get(t2, "animationLookTransform");
			F_defaultPos = Get(t3, "defaultPos");
			P_usingPrimary = Get(t3, "isUsingPrimary");
			P_usingSecondary = Get(t3, "isUsingSecondary");
		}

		internal static object LocalCharacter()
		{
			return AsAlive(F_localCharacter.GetValue(null));
		}

		internal static object Data(object character)
		{
			if (character != null)
			{
				return AsAlive(F_data.GetValue(character));
			}
			return null;
		}

		internal static object CurrentItem(object character)
		{
			object obj = Data(character);
			if (obj != null)
			{
				return AsAlive(F_currentItem.GetValue(obj));
			}
			return null;
		}

		internal static Vector3 DefaultPos(object item)
		{
			//IL_0014: 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)
			if (item != null)
			{
				return (Vector3)F_defaultPos.GetValue(item);
			}
			return Vector3.zero;
		}

		internal static bool IsUsing(object item)
		{
			if (item != null)
			{
				if (!(bool)P_usingPrimary.GetValue(item))
				{
					return (bool)P_usingSecondary.GetValue(item);
				}
				return true;
			}
			return false;
		}

		internal static Rigidbody HandRig(object character, string part)
		{
			if (_getBodypartRig == null)
			{
				_bodypartType = GameType("BodypartType");
				_getBodypartRig = AccessTools.Method(GameType("Character"), "GetBodypartRig", new Type[1] { _bodypartType }, (Type[])null);
			}
			object? obj = _getBodypartRig.Invoke(character, new object[1] { Enum.Parse(_bodypartType, part) });
			return (Rigidbody)((obj is Rigidbody) ? obj : null);
		}

		internal static Rigidbody ItemRig(object item)
		{
			object value = (_rig ?? (_rig = Get(GameType("Item"), "rig"))).GetValue(item);
			return (Rigidbody)((value is Rigidbody) ? value : null);
		}

		internal static bool RightHandOnly(object item)
		{
			return (bool)(_rightHandOnly ?? (_rightHandOnly = Get(GameType("Item"), "rightHandOnly"))).GetValue(item);
		}

		internal static Vector3 LeftGripWorld(object character, object item)
		{
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			object value = (_items ?? (_items = Get(GameType("Character").GetNestedType("CharacterRefs", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), "items"))).GetValue(F_refs.GetValue(character));
			if ((object)_posLeftWorld == null)
			{
				_posLeftWorld = AccessTools.Method(GameType("CharacterItems"), "GetItemPosLeftWorld", (Type[])null, (Type[])null);
			}
			return (Vector3)_posLeftWorld.Invoke(value, new object[1] { item });
		}

		internal static void ScaleLeftIKWeight(object character, float k)
		{
			object value = (_ikLeft ?? (_ikLeft = Get(GameType("Character").GetNestedType("CharacterRefs", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic), "ikLeft"))).GetValue(F_refs.GetValue(character));
			if (value != null)
			{
				if ((object)_weight == null)
				{
					_weight = value.GetType().GetProperty("weight", BindingFlags.Instance | BindingFlags.Public);
				}
				if (!(_weight == null))
				{
					_weight.SetValue(value, (float)_weight.GetValue(value) * k);
				}
			}
		}

		internal static bool HasPrimaryAction(object item)
		{
			try
			{
				object obj = AccessTools.Field(item.GetType(), "UIData")?.GetValue(item);
				object obj2 = ((obj == null) ? null : AccessTools.Field(obj.GetType(), "hasMainInteract")?.GetValue(obj));
				if (obj2 is bool && !(bool)obj2)
				{
					return false;
				}
				if ((object)_canUsePrimary == null)
				{
					_canUsePrimary = AccessTools.Method(GameType("Item"), "CanUsePrimary", (Type[])null, (Type[])null);
				}
				return _canUsePrimary == null || (bool)_canUsePrimary.Invoke(item, null);
			}
			catch
			{
				return true;
			}
		}

		internal static bool GetBool(Member m, object obj)
		{
			return (bool)m.GetValue(obj);
		}

		internal static object GetField(object obj, string name)
		{
			if (obj != null)
			{
				return AsAlive(AccessTools.Field(obj.GetType(), name)?.GetValue(obj));
			}
			return null;
		}

		private static object AsAlive(object o)
		{
			Object val = (Object)((o is Object) ? o : null);
			if (val == null)
			{
				return o;
			}
			if (!Object.op_Implicit(val))
			{
				return null;
			}
			return o;
		}
	}
	internal class MouseReader
	{
		private readonly PropertyInfo _current;

		private PropertyInfo _left;

		private PropertyInfo _pressed;

		private PropertyInfo _held;

		public MouseReader()
		{
			_current = AccessTools.TypeByName("UnityEngine.InputSystem.Mouse")?.GetProperty("current", BindingFlags.Static | BindingFlags.Public);
		}

		private object Button()
		{
			object obj = _current?.GetValue(null);
			if (obj == null)
			{
				return null;
			}
			if ((object)_left == null)
			{
				_left = obj.GetType().GetProperty("leftButton");
			}
			return _left?.GetValue(obj);
		}

		public bool LeftPressedThisFrame()
		{
			try
			{
				object obj = Button();
				if (obj == null)
				{
					return Input.GetMouseButtonDown(0);
				}
				if ((object)_pressed == null)
				{
					_pressed = obj.GetType().GetProperty("wasPressedThisFrame");
				}
				return (bool)_pressed.GetValue(obj);
			}
			catch
			{
				return false;
			}
		}

		public bool LeftHeld()
		{
			try
			{
				object obj = Button();
				if (obj == null)
				{
					return Input.GetMouseButton(0);
				}
				if ((object)_held == null)
				{
					_held = obj.GetType().GetProperty("isPressed");
				}
				return (bool)_held.GetValue(obj);
			}
			catch
			{
				return false;
			}
		}
	}
	internal class InputReader
	{
		private static readonly Dictionary<string, string[]> KeyAliases = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase)
		{
			{
				"Alt",
				new string[2] { "LeftAlt", "RightAlt" }
			},
			{
				"Ctrl",
				new string[2] { "LeftCtrl", "RightCtrl" }
			},
			{
				"Control",
				new string[2] { "LeftCtrl", "RightCtrl" }
			},
			{
				"Shift",
				new string[2] { "LeftShift", "RightShift" }
			},
			{
				"LAlt",
				new string[1] { "LeftAlt" }
			},
			{
				"RAlt",
				new string[1] { "RightAlt" }
			},
			{
				"LCtrl",
				new string[1] { "LeftCtrl" }
			},
			{
				"RCtrl",
				new string[1] { "RightCtrl" }
			},
			{
				"LShift",
				new string[1] { "LeftShift" }
			},
			{
				"RShift",
				new string[1] { "RightShift" }
			},
			{
				"Tilde",
				new string[1] { "Backquote" }
			},
			{
				"Ё",
				new string[1] { "Backquote" }
			}
		};

		private static readonly Dictionary<string, string> MouseAliases = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
		{
			{ "Mouse3", "middleButton" },
			{ "MiddleMouse", "middleButton" },
			{ "MMB", "middleButton" },
			{ "Mouse4", "backButton" },
			{ "MouseBack", "backButton" },
			{ "Mouse5", "forwardButton" },
			{ "MouseForward", "forwardButton" }
		};

		private static readonly Dictionary<string, KeyCode> LegacyAliases = new Dictionary<string, KeyCode>(StringComparer.OrdinalIgnoreCase)
		{
			{
				"Alt",
				(KeyCode)308
			},
			{
				"Ctrl",
				(KeyCode)306
			},
			{
				"Control",
				(KeyCode)306
			},
			{
				"Shift",
				(KeyCode)304
			},
			{
				"LeftCtrl",
				(KeyCode)306
			},
			{
				"RightCtrl",
				(KeyCode)305
			},
			{
				"Mouse3",
				(KeyCode)325
			},
			{
				"Mouse4",
				(KeyCode)326
			},
			{
				"Mouse5",
				(KeyCode)327
			},
			{
				"Backquote",
				(KeyCode)96
			}
		};

		private readonly List<object> _keys = new List<object>();

		private readonly string _mouseButton;

		private readonly PropertyInfo _keyboard;

		private readonly PropertyInfo _indexer;

		private readonly PropertyInfo _mouse;

		private readonly KeyCode _legacy;

		private readonly Dictionary<string, PropertyInfo> _props = new Dictionary<string, PropertyInfo>();

		public unsafe static string FromKeyCode(KeyCode k)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_0005: 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_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected I4, but got Unknown
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_0046: 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_0066: Expected I4, but got Unknown
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			if ((int)k <= 96)
			{
				if ((int)k != 0)
				{
					if ((int)k != 13)
					{
						if ((int)k != 96)
						{
							goto IL_00aa;
						}
						return "Backquote";
					}
					return "Enter";
				}
			}
			else
			{
				if ((int)k == 271)
				{
					return "NumpadEnter";
				}
				switch (k - 305)
				{
				case 1:
					return "LeftCtrl";
				case 0:
					return "RightCtrl";
				case 5:
					return "LeftMeta";
				case 4:
					return "RightMeta";
				case 2:
				case 3:
					goto IL_00aa;
				}
				switch (k - 323)
				{
				case 0:
				case 1:
					break;
				case 2:
					return "Mouse3";
				case 3:
					return "Mouse4";
				case 4:
					return "Mouse5";
				default:
					goto IL_00aa;
				}
			}
			return "F";
			IL_00aa:
			string text = ((object)(*(KeyCode*)(&k))/*cast due to .constrained prefix*/).ToString();
			if (text.StartsWith("Alpha"))
			{
				return "Digit" + text.Substring(5);
			}
			if (text.StartsWith("Keypad"))
			{
				return "Numpad" + text.Substring(6);
			}
			return text;
		}

		public InputReader(string keyName)
		{
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			keyName = (keyName ?? "F").Trim();
			Type type = AccessTools.TypeByName("UnityEngine.InputSystem.Keyboard");
			Type type2 = AccessTools.TypeByName("UnityEngine.InputSystem.Key");
			_mouse = AccessTools.TypeByName("UnityEngine.InputSystem.Mouse")?.GetProperty("current", BindingFlags.Static | BindingFlags.Public);
			if (MouseAliases.TryGetValue(keyName, out var value))
			{
				_mouseButton = value;
			}
			else if (type != null && type2 != null)
			{
				_keyboard = type.GetProperty("current", BindingFlags.Static | BindingFlags.Public);
				_indexer = type.GetProperty("Item", new Type[1] { type2 });
				string[] value2;
				string[] array = (KeyAliases.TryGetValue(keyName, out value2) ? value2 : new string[1] { keyName });
				foreach (string text in array)
				{
					try
					{
						_keys.Add(Enum.Parse(type2, text, ignoreCase: true));
					}
					catch
					{
						Plugin.Error("Неизвестная клавиша '" + text + "' — используется F");
					}
				}
				if (_keys.Count == 0)
				{
					_keys.Add(Enum.Parse(type2, "F"));
				}
			}
			if (!LegacyAliases.TryGetValue(keyName, out _legacy) && !Enum.TryParse<KeyCode>(keyName, ignoreCase: true, out _legacy))
			{
				_legacy = (KeyCode)102;
			}
		}

		public bool WasPressedThisFrame()
		{
			return Read("wasPressedThisFrame", () => Input.GetKeyDown(_legacy));
		}

		public bool IsHeld()
		{
			return Read("isPressed", () => Input.GetKey(_legacy));
		}

		private bool Read(string prop, Func<bool> legacy)
		{
			try
			{
				if (_mouseButton != null)
				{
					object obj = _mouse?.GetValue(null);
					if (obj == null)
					{
						return legacy();
					}
					return Check(obj.GetType().GetProperty(_mouseButton)?.GetValue(obj), prop);
				}
				if (_keyboard != null && _indexer != null && _keys.Count > 0)
				{
					object value = _keyboard.GetValue(null);
					if (value == null)
					{
						return false;
					}
					foreach (object key in _keys)
					{
						if (Check(_indexer.GetValue(value, new object[1] { key }), prop))
						{
							return true;
						}
					}
					return false;
				}
				return legacy();
			}
			catch
			{
				return false;
			}
		}

		private bool Check(object control, string prop)
		{
			if (control == null)
			{
				return false;
			}
			if (!_props.TryGetValue(prop, out var value))
			{
				value = (_props[prop] = control.GetType().GetProperty(prop));
			}
			if (value != null)
			{
				return (bool)value.GetValue(control);
			}
			return false;
		}

		public static string IconTag(string keyName)
		{
			keyName = (keyName ?? "F").Trim();
			if (MouseAliases.TryGetValue(keyName, out var value))
			{
				return SpriteTag("inputPathToSpriteTagMouse", value) ?? ("[" + keyName + "]");
			}
			string[] value2;
			string key = (KeyAliases.TryGetValue(keyName, out value2) ? value2[0] : keyName);
			return SpriteTag("inputPathToSpriteTagKeyboard", key) ?? ("[" + keyName + "]");
		}

		internal static string SpriteTag(string dictName, string key)
		{
			try
			{
				Type type = Refs.GameType("InputSpriteData");
				object obj = null;
				Type type2 = type;
				while (type2 != null && obj == null)
				{
					obj = type2.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)?.GetValue(null);
					type2 = type2.BaseType;
				}
				if (AccessTools.Field(type, dictName)?.GetValue(obj) is Dictionary<string, string> dictionary)
				{
					foreach (KeyValuePair<string, string> item in dictionary)
					{
						if (string.Equals(item.Key, key, StringComparison.OrdinalIgnoreCase))
						{
							return item.Value;
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Error("Не нашёл иконку клавиши: " + ex.Message);
			}
			return null;
		}
	}
}