Decompiled source of GrandpaControlMod v1.0.0

Antro.GrandpaControl.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Pathfinding;
using RootMotion.FinalIK;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;
using UnityEngine.UI;
using UnityEngine.UIElements;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("Antro.GrandpaControl")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Antro.GrandpaControl")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0.0")]
[assembly: AssemblyProduct("Antro.GrandpaControl")]
[assembly: AssemblyTitle("Antro.GrandpaControl")]
[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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DiscordInviteMod
{
	[BepInPlugin("Antro.discord_invite", "Discord Invite Button", "1.0.3")]
	public class DiscordInvitePlugin : BaseUnityPlugin
	{
		private const string SharedObjectName = "SharedDiscordInviteButton_BG";

		private void Awake()
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Expected O, but got Unknown
			if ((Object)(object)GameObject.Find("SharedDiscordInviteButton_BG") == (Object)null)
			{
				GameObject val = new GameObject("SharedDiscordInviteButton_BG");
				Object.DontDestroyOnLoad((Object)(object)val);
				val.AddComponent<DiscordInviteComponent>();
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Discord Invite Button initialized successfully!");
			}
			else
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Discord Invite Button already exists from another mod. Skipping creation.");
			}
		}
	}
	public class DiscordInviteComponent : MonoBehaviour
	{
		private readonly string discordUrl = "https://discord.gg/bPjcrJxBmP";

		private readonly string logoUrl = "https://i.imgur.com/48jKo1r_d.png?maxwidth=520&shape=thumb&fidelity=high";

		private readonly string arrowUrl = "https://i.imgur.com/TUT8ICu_d.png?maxwidth=520&shape=thumb&fidelity=high";

		private readonly float logoSize = 300f;

		private readonly float padding = 40f;

		private readonly float arrowSize = 160f;

		private readonly float baseRadius = 260f;

		private readonly float animAmplitude = 25f;

		private readonly float animSpeed = 5f;

		private Texture2D logoTexture;

		private Texture2D arrowTexture;

		private GUIStyle transparentStyle;

		private string folderPath;

		private bool hasClickedLogo = false;

		private const string PrefsKey = "Antro_DiscordInvite_HasClicked";

		private bool shouldShowButton = false;

		private bool isSubMenuOpen = false;

		private HashSet<Button> hookedButtons = new HashSet<Button>();

		private void Start()
		{
			hasClickedLogo = PlayerPrefs.GetInt("Antro_DiscordInvite_HasClicked", 0) == 1;
			folderPath = Path.Combine(Paths.PluginPath, "DiscordInviteMod");
			if (!Directory.Exists(folderPath))
			{
				Directory.CreateDirectory(folderPath);
			}
			((MonoBehaviour)this).StartCoroutine(LoadOrDownloadImage(logoUrl, "DiscordLogoCache.png", delegate(Texture2D result)
			{
				logoTexture = result;
			}));
			if (!hasClickedLogo)
			{
				((MonoBehaviour)this).StartCoroutine(LoadOrDownloadImage(arrowUrl, "DiscordArrowCache.png", delegate(Texture2D result)
				{
					arrowTexture = result;
				}));
			}
			((MonoBehaviour)this).StartCoroutine(CheckMenuState());
		}

		private void Update()
		{
			if (Input.GetKeyDown((KeyCode)27))
			{
				isSubMenuOpen = false;
			}
		}

		private IEnumerator CheckMenuState()
		{
			while (true)
			{
				GameObject mainButtonsObj = GameObject.Find("Canvas/Menu/Button parent/Buttons");
				if ((Object)(object)mainButtonsObj == (Object)null)
				{
					GameObject temp = GameObject.Find("Buttons");
					if ((Object)(object)temp != (Object)null && (Object)(object)temp.transform.parent != (Object)null && ((Object)temp.transform.parent).name == "Button parent")
					{
						mainButtonsObj = temp;
					}
				}
				if ((Object)(object)mainButtonsObj == (Object)null)
				{
					shouldShowButton = false;
					isSubMenuOpen = false;
				}
				else
				{
					CanvasGroup cg = mainButtonsObj.GetComponentInParent<CanvasGroup>();
					if (!((Object)(object)cg == (Object)null) && (!(cg.alpha > 0.01f) || !cg.interactable))
					{
						shouldShowButton = false;
						isSubMenuOpen = false;
					}
					else
					{
						shouldShowButton = !isSubMenuOpen;
						Button[] buttons = mainButtonsObj.GetComponentsInChildren<Button>(true);
						Button[] array = buttons;
						foreach (Button btn in array)
						{
							if (hookedButtons.Add(btn))
							{
								((UnityEvent)btn.onClick).AddListener((UnityAction)delegate
								{
									isSubMenuOpen = true;
								});
							}
						}
					}
				}
				yield return (object)new WaitForSeconds(0.5f);
			}
		}

		private IEnumerator LoadOrDownloadImage(string url, string fileName, Action<Texture2D> onLoaded)
		{
			string localPath = Path.Combine(folderPath, fileName);
			if (File.Exists(localPath))
			{
				string fileUrl = "file://" + localPath.Replace("\\", "/");
				UnityWebRequest uwr = UnityWebRequestTexture.GetTexture(fileUrl);
				try
				{
					yield return uwr.SendWebRequest();
					if ((int)uwr.result == 1)
					{
						onLoaded?.Invoke(DownloadHandlerTexture.GetContent(uwr));
						yield break;
					}
				}
				finally
				{
					((IDisposable)uwr)?.Dispose();
				}
			}
			UnityWebRequest uwr2 = UnityWebRequestTexture.GetTexture(url);
			try
			{
				yield return uwr2.SendWebRequest();
				if ((int)uwr2.result == 1)
				{
					Texture2D tex = DownloadHandlerTexture.GetContent(uwr2);
					onLoaded?.Invoke(tex);
					try
					{
						File.WriteAllBytes(localPath, uwr2.downloadHandler.data);
					}
					catch
					{
					}
				}
			}
			finally
			{
				((IDisposable)uwr2)?.Dispose();
			}
		}

		private void OnGUI()
		{
			//IL_0271: Unknown result type (might be due to invalid IL or missing references)
			//IL_0276: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Expected O, but got Unknown
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_0242: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			if (!shouldShowButton || ((Object)(object)NetworkManager.Singleton != (Object)null && (NetworkManager.Singleton.IsClient || NetworkManager.Singleton.IsServer)))
			{
				return;
			}
			GUI.depth = -1000;
			Rect val = default(Rect);
			((Rect)(ref val))..ctor((float)Screen.width - logoSize - padding, padding, logoSize, logoSize);
			if (!hasClickedLogo && (Object)(object)logoTexture != (Object)null && (Object)(object)arrowTexture != (Object)null)
			{
				float num = ((Rect)(ref val)).x + logoSize / 2f;
				float num2 = ((Rect)(ref val)).y + logoSize / 2f;
				float[,] array = new float[3, 3]
				{
					{
						(float)Math.PI,
						90f,
						0f
					},
					{
						(float)Math.PI * 3f / 4f,
						45f,
						2f
					},
					{
						(float)Math.PI / 2f,
						0f,
						4f
					}
				};
				Rect val2 = default(Rect);
				for (int i = 0; i < 3; i++)
				{
					float num3 = array[i, 0];
					float num4 = array[i, 1];
					float num5 = array[i, 2];
					float num6 = baseRadius + Mathf.Sin(Time.realtimeSinceStartup * animSpeed + num5) * animAmplitude;
					float num7 = num + Mathf.Cos(num3) * num6;
					float num8 = num2 + Mathf.Sin(num3) * num6;
					((Rect)(ref val2))..ctor(num7 - arrowSize / 2f, num8 - arrowSize / 2f, arrowSize, arrowSize);
					Matrix4x4 matrix = GUI.matrix;
					GUIUtility.RotateAroundPivot(num4, new Vector2(num7, num8));
					GUI.DrawTexture(val2, (Texture)(object)arrowTexture, (ScaleMode)2, true);
					GUI.matrix = matrix;
				}
			}
			if ((Object)(object)logoTexture != (Object)null)
			{
				if (transparentStyle == null)
				{
					transparentStyle = new GUIStyle(GUI.skin.button);
					transparentStyle.normal.background = null;
					transparentStyle.hover.background = null;
					transparentStyle.active.background = null;
				}
				if (GUI.Button(val, (Texture)(object)logoTexture, transparentStyle))
				{
					HandleLogoClick();
				}
			}
			else
			{
				GUIStyle val3 = new GUIStyle(GUI.skin.button)
				{
					fontSize = 14,
					fontStyle = (FontStyle)1
				};
				if (GUI.Button(new Rect((float)(Screen.width - 150) - padding, padding, 150f, 50f), "Discord", val3))
				{
					HandleLogoClick();
				}
			}
		}

		private void HandleLogoClick()
		{
			if (!hasClickedLogo)
			{
				hasClickedLogo = true;
				PlayerPrefs.SetInt("Antro_DiscordInvite_HasClicked", 1);
				PlayerPrefs.Save();
				if ((Object)(object)arrowTexture != (Object)null)
				{
					Object.Destroy((Object)(object)arrowTexture);
					arrowTexture = null;
				}
			}
			Application.OpenURL(discordUrl);
		}
	}
}
namespace BurglinGnomesGrandpaMod
{
	public class CustomGrandpaController : MonoBehaviour
	{
		private struct BodyState
		{
			public Rigidbody Rb;

			public bool WasKinematic;

			public bool HadGravity;

			public bool HadDetectCollisions;

			public RigidbodyConstraints Constraints;
		}

		private Vector3 lastRawMousePos;

		private float originalCameraFOV = 70f;

		public PlayerNetworking localGnome;

		public bool isControlledByMe;

		public Camera myCamera;

		private Animator anim;

		private Transform headBone;

		private Transform rightHandBone;

		private Transform rightShoulderBone;

		private HumanAILink aiLink;

		private FullBodyBipedIK fbbik;

		private bool initialized;

		private float cameraPitch;

		private float cameraYaw;

		private Vector3 controlledPosition;

		private bool aiSuppressed;

		private float lastMoveInputMagnitude;

		private float verticalVelocity = 0f;

		private float handDistance = 1.1f;

		private float nextActionTime = 0f;

		private Transform originalCameraParent;

		private Vector3 originalCameraLocalPos;

		private Quaternion originalCameraLocalRot;

		private Coroutine standFixRoutine;

		private Coroutine cameraFollowGnomeRoutine;

		private Coroutine forceHideUIRoutine;

		private readonly List<MonoBehaviour> disabledGrandpaScripts = new List<MonoBehaviour>();

		private readonly List<MonoBehaviour> disabledCameraScripts = new List<MonoBehaviour>();

		private readonly List<MonoBehaviour> disabledGnomeScripts = new List<MonoBehaviour>();

		private readonly List<Rigidbody> frozenGnomeBodies = new List<Rigidbody>();

		private readonly List<BodyState> modifiedGrandpaBodies = new List<BodyState>();

		private GameObject grandpaCrosshairCanvas;

		public Vector3 debugWeaponPos = Vector3.zero;

		public Vector3 debugWeaponRot = Vector3.zero;

		private bool showDebugMenu = false;

		private string debugMode = "POS";

		private bool wasCrouching = false;

		private float crouchLockEndTime = 0f;

		private void Update()
		{
			//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_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_00e9: 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_006b: 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_0077: 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_00a2: 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_00d9: 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_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0246: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			if (!isControlledByMe || (Object)(object)myCamera == (Object)null || (Object)(object)aiLink == (Object)null)
			{
				return;
			}
			UpdateDebugMenu();
			float num = Input.GetAxisRaw("Mouse X");
			float num2 = Input.GetAxisRaw("Mouse Y");
			Vector3 mousePosition = Input.mousePosition;
			if (lastRawMousePos != Vector3.zero)
			{
				Vector3 val = mousePosition - lastRawMousePos;
				if (Mathf.Abs(num) < 0.001f && Mathf.Abs(val.x) > 0.01f)
				{
					num = val.x * 0.1f;
				}
				if (Mathf.Abs(num2) < 0.001f && Mathf.Abs(val.y) > 0.01f)
				{
					num2 = val.y * 0.1f;
				}
			}
			lastRawMousePos = mousePosition;
			HandleLook(num, num2);
			bool flag = Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)99);
			if ((Object)(object)anim != (Object)null)
			{
				TrySetAnimatorBool("Crouched", flag);
			}
			HandleMovement(flag);
			bool flag2 = (Object)(object)anim != (Object)null && anim.GetBool("Carrying");
			bool flag3 = (Object)(object)aiLink.ObjectInHand != (Object)null;
			if (Input.GetMouseButtonDown(0) && Time.time >= nextActionTime)
			{
				if (flag3)
				{
					SendAction(2, 0uL, ((Component)myCamera).transform.forward);
					nextActionTime = Time.time + 0.5f;
				}
				else if (flag2)
				{
					SendAction(3, 0uL, ((Component)myCamera).transform.forward);
					nextActionTime = Time.time + 1f;
				}
				else
				{
					PlayLocalGrabAnimation();
				}
			}
			if (Input.GetKeyDown((KeyCode)113))
			{
				if (flag3)
				{
					SendAction(4, 0uL, ((Component)myCamera).transform.forward);
				}
				else if (flag2)
				{
					SendAction(1, 0uL);
				}
			}
			if (Input.GetKeyDown((KeyCode)101) && Time.time >= nextActionTime)
			{
				TryRaycastInteraction();
			}
		}

		private void LateUpdate()
		{
			if (isControlledByMe && !((Object)(object)myCamera == (Object)null))
			{
				HandleCamera();
				HandleIKReaching();
			}
		}

		private void HandleIKReaching()
		{
			//IL_0065: 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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Invalid comparison between Unknown and I4
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Invalid comparison between Unknown and I4
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Invalid comparison between Unknown and I4
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: 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_01fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_027d: Unknown result type (might be due to invalid IL or missing references)
			//IL_028d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ad: 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_02cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: 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_03b6: 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_0362: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)fbbik == (Object)null || (Object)(object)myCamera == (Object)null || (Object)(object)aiLink == (Object)null)
			{
				return;
			}
			bool mouseButton = Input.GetMouseButton(1);
			bool flag = (Object)(object)aiLink.ObjectInHand != (Object)null;
			bool flag2 = false;
			if (flag)
			{
				SpecificItemType itemType = aiLink.ObjectInHand.ItemType;
				if ((int)itemType == 97 || (int)itemType == 4 || (int)itemType == 98)
				{
					flag2 = true;
				}
			}
			IKEffector rightHandEffector = fbbik.solver.rightHandEffector;
			IKEffector leftHandEffector = fbbik.solver.leftHandEffector;
			AimIK val = null;
			FieldInfo field = typeof(HumanAILink).GetField("aim", BindingFlags.Instance | BindingFlags.NonPublic);
			if (field != null)
			{
				object? value = field.GetValue(aiLink);
				val = (AimIK)((value is AimIK) ? value : null);
			}
			if (mouseButton)
			{
				TrySetAnimatorBool("Reach", value: true);
				TrySetAnimatorBool("Reaching", value: true);
				if (flag2 && (Object)(object)val != (Object)null)
				{
					rightHandEffector.positionWeight = Mathf.Lerp(rightHandEffector.positionWeight, 0f, Time.deltaTime * 10f);
					leftHandEffector.positionWeight = Mathf.Lerp(leftHandEffector.positionWeight, 0f, Time.deltaTime * 10f);
					Vector3 iKPosition = ((Component)myCamera).transform.position + ((Component)myCamera).transform.forward * 50f;
					((IKSolver)val.solver).IKPosition = iKPosition;
					((IKSolver)val.solver).IKPositionWeight = Mathf.Lerp(((IKSolver)val.solver).IKPositionWeight, 1f, Time.deltaTime * 10f);
					return;
				}
				if ((Object)(object)val != (Object)null)
				{
					((IKSolver)val.solver).IKPositionWeight = 0f;
				}
				float y = Input.mouseScrollDelta.y;
				handDistance = Mathf.Clamp(handDistance + y * 0.3f, 1.5f, 2.4f);
				leftHandEffector.positionWeight = Mathf.Lerp(leftHandEffector.positionWeight, 0f, Time.deltaTime * 15f);
				rightHandEffector.positionWeight = Mathf.Lerp(rightHandEffector.positionWeight, 1f, Time.deltaTime * 15f);
				Vector3 val2 = (rightHandEffector.position = ((Component)myCamera).transform.position + ((Component)myCamera).transform.forward * handDistance - ((Component)myCamera).transform.up * 0.2f + ((Component)myCamera).transform.right * 0.1f);
				((IKSolver)fbbik.solver).Update();
				if (flag || !(Time.time >= nextActionTime))
				{
					return;
				}
				PlayerNetworking val3 = null;
				PlayerNetworking[] array = Object.FindObjectsByType<PlayerNetworking>((FindObjectsInactive)0, (FindObjectsSortMode)0);
				PlayerNetworking[] array2 = array;
				foreach (PlayerNetworking val4 in array2)
				{
					if (!((Object)(object)val4 == (Object)null) && !((GameEntityBase)val4).IsDead && !((GameEntityBase)val4).IsGrabbed)
					{
						float num = Vector3.Distance(val2, ((GameEntityBase)val4).Center);
						if (num <= 2.5f)
						{
							val3 = val4;
							break;
						}
					}
				}
				if ((Object)(object)val3 != (Object)null)
				{
					SendAction(0, ((NetworkBehaviour)val3).OwnerClientId);
					nextActionTime = Time.time + 1f;
				}
			}
			else
			{
				TrySetAnimatorBool("Reach", value: false);
				TrySetAnimatorBool("Reaching", value: false);
				rightHandEffector.positionWeight = Mathf.Lerp(rightHandEffector.positionWeight, 0f, Time.deltaTime * 10f);
				leftHandEffector.positionWeight = Mathf.Lerp(leftHandEffector.positionWeight, 0f, Time.deltaTime * 10f);
				if ((Object)(object)val != (Object)null)
				{
					((IKSolver)val.solver).IKPositionWeight = Mathf.Lerp(((IKSolver)val.solver).IKPositionWeight, 0f, Time.deltaTime * 10f);
				}
			}
		}

		private void TryRaycastInteraction()
		{
			//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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_006e: 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_0086: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)localGnome == (Object)null) && !((Object)(object)myCamera == (Object)null))
			{
				Vector3 position = ((Component)myCamera).transform.position;
				Vector3 forward = ((Component)myCamera).transform.forward;
				RaycastHit hit = default(RaycastHit);
				RaycastHit hit2 = default(RaycastHit);
				if ((!Physics.Raycast(position, forward, ref hit, 8f, -5, (QueryTriggerInteraction)2) || !ProcessHit(hit)) && Physics.Raycast(position, forward, ref hit2, 8f, -5, (QueryTriggerInteraction)1))
				{
					ProcessHit(hit2);
				}
			}
		}

		private bool ProcessHit(RaycastHit hit)
		{
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Invalid comparison between Unknown and I4
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Invalid comparison between Unknown and I4
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Invalid comparison between Unknown and I4
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Invalid comparison between Unknown and I4
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Invalid comparison between Unknown and I4
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Invalid comparison between Unknown and I4
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Invalid comparison between Unknown and I4
			StealableObject componentInParent = ((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<StealableObject>();
			if ((Object)(object)componentInParent != (Object)null && (Object)(object)aiLink != (Object)null && (Object)(object)aiLink.ObjectInHand == (Object)null && (Object)(object)aiLink.kidnapper.CurrentlyHeld == (Object)null && ((Object)(object)((Component)componentInParent).GetComponent<Gun>() != (Object)null || (int)componentInParent.ItemType == 97 || (int)componentInParent.ItemType == 4 || (int)componentInParent.ItemType == 98 || (int)componentInParent.ItemType == 6 || (int)componentInParent.ItemType == 94 || (int)componentInParent.ItemType == 96 || (Object)(object)((Component)componentInParent).GetComponent("Chainsaw") != (Object)null || (Object)(object)((Component)componentInParent).GetComponent("Leafblower") != (Object)null || (componentInParent.Category & 8) == 8))
			{
				SendAction(5, ((NetworkBehaviour)componentInParent).NetworkObjectId);
				nextActionTime = Time.time + 1f;
				return true;
			}
			OpenableInteractable componentInParent2 = ((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<OpenableInteractable>();
			if ((Object)(object)componentInParent2 != (Object)null)
			{
				object obj = ((object)componentInParent2).GetType().GetProperty("State", BindingFlags.Instance | BindingFlags.Public)?.GetValue(componentInParent2);
				if (obj != null)
				{
					int num = (int)obj;
					if (num != 2)
					{
						componentInParent2.ToggleRpc();
						return true;
					}
					FieldInfo field = ((object)componentInParent2).GetType().GetField("currentOpenPercentage", BindingFlags.Instance | BindingFlags.NonPublic);
					if (field != null)
					{
						float num2 = (float)field.GetValue(componentInParent2);
						string text = ((Object)((Component)componentInParent2).gameObject).name.ToLowerInvariant();
						if ((text.Contains("refrigerator") || text.Contains("fridge") || text.Contains("kitchendoor_bottom_d")) ? (num2 < 0.5f) : (num2 > 0.5f))
						{
							componentInParent2.UnClasp();
							componentInParent2.Open();
						}
						else
						{
							componentInParent2.Close();
						}
						return true;
					}
				}
			}
			ToggleableInteractable componentInParent3 = ((Component)((RaycastHit)(ref hit)).collider).GetComponentInParent<ToggleableInteractable>();
			if ((Object)(object)componentInParent3 != (Object)null)
			{
				componentInParent3.ToggleRpc();
				return true;
			}
			return false;
		}

		private void PlayLocalGrabAnimation()
		{
			if ((Object)(object)anim != (Object)null)
			{
				anim.SetTrigger("Grab");
				if ((Object)(object)aiLink != (Object)null)
				{
					GrandpaModPatches.TrySendCaughtEvent(aiLink);
				}
			}
		}

		private unsafe void SendAction(byte actionId, ulong targetId, Vector3 dir = default(Vector3))
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)NetworkManager.Singleton != (Object)null))
			{
				return;
			}
			if (NetworkManager.Singleton.IsServer)
			{
				GrandpaModPatches.ExecuteGrandpaAction(actionId, targetId, dir);
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(21, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<byte>(ref actionId, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref targetId, default(ForPrimitives));
				((FastBufferWriter)(ref val)).WriteValueSafe(ref dir);
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage("GrandpaActionMsg", 0uL, val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
		}

		private void SetupCamera()
		{
			//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_0073: 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)
			myCamera = Camera.main;
			if ((Object)(object)myCamera == (Object)null)
			{
				myCamera = Object.FindAnyObjectByType<Camera>();
			}
			if (!((Object)(object)myCamera != (Object)null))
			{
				return;
			}
			originalCameraParent = ((Component)myCamera).transform.parent;
			originalCameraLocalPos = ((Component)myCamera).transform.localPosition;
			originalCameraLocalRot = ((Component)myCamera).transform.localRotation;
			originalCameraFOV = myCamera.fieldOfView;
			MonoBehaviour[] components = ((Component)myCamera).GetComponents<MonoBehaviour>();
			foreach (MonoBehaviour val in components)
			{
				if ((Object)(object)val != (Object)null && ((Behaviour)val).enabled)
				{
					disabledCameraScripts.Add(val);
					((Behaviour)val).enabled = false;
				}
			}
			((Component)myCamera).transform.SetParent((Transform)null);
			myCamera.fieldOfView = 75f;
		}

		private void RestoreCameraScripts()
		{
			if ((Object)(object)myCamera != (Object)null)
			{
				myCamera.fieldOfView = originalCameraFOV;
			}
			foreach (MonoBehaviour disabledCameraScript in disabledCameraScripts)
			{
				if ((Object)(object)disabledCameraScript != (Object)null)
				{
					((Behaviour)disabledCameraScript).enabled = true;
				}
			}
			disabledCameraScripts.Clear();
		}

		public void HandleLook(float mouseX, float mouseY)
		{
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			cameraYaw += mouseX * 2.5f;
			cameraPitch -= mouseY * 2.5f;
			cameraPitch = Mathf.Clamp(cameraPitch, -80f, 80f);
			((Component)this).transform.rotation = Quaternion.Euler(0f, cameraYaw, 0f);
		}

		public void HandleCamera()
		{
			//IL_0051: 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_0035: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)myCamera == (Object)null))
			{
				Vector3 val = (((Object)(object)headBone != (Object)null) ? headBone.position : (((Component)this).transform.position + ((Component)this).transform.up * 1.92f));
				Vector3 position = val - ((Component)this).transform.up * 0f + ((Component)this).transform.forward * 1f;
				((Component)myCamera).transform.position = position;
				((Component)myCamera).transform.rotation = Quaternion.Euler(cameraPitch, ((Component)this).transform.eulerAngles.y, 0f);
			}
		}

		private void Start()
		{
			anim = ((Component)this).GetComponentInChildren<Animator>();
			aiLink = ((Component)this).GetComponent<HumanAILink>();
			fbbik = ((Component)this).GetComponentInChildren<FullBodyBipedIK>();
			if ((Object)(object)fbbik == (Object)null && (Object)(object)aiLink != (Object)null)
			{
				FieldInfo field = typeof(HumanAILink).GetField("ik", BindingFlags.Instance | BindingFlags.NonPublic);
				if (field != null)
				{
					ref FullBodyBipedIK reference = ref fbbik;
					object? value = field.GetValue(aiLink);
					reference = (FullBodyBipedIK)((value is FullBodyBipedIK) ? value : null);
				}
			}
			if ((Object)(object)anim != (Object)null && anim.isHuman)
			{
				headBone = anim.GetBoneTransform((HumanBodyBones)10);
				rightHandBone = anim.GetBoneTransform((HumanBodyBones)18);
				rightShoulderBone = anim.GetBoneTransform((HumanBodyBones)14);
				if ((Object)(object)rightShoulderBone == (Object)null)
				{
					rightShoulderBone = ((Component)this).transform;
				}
			}
		}

		public void SetControlState(PlayerNetworking localPlayer, bool shouldControl, bool manualMode)
		{
			localGnome = localPlayer ?? ServerManager.GetLocalPlayer();
			if (manualMode)
			{
				EnsureManualSuppression();
			}
			else
			{
				ReleaseManualSuppression();
			}
			if (shouldControl != isControlledByMe)
			{
				isControlledByMe = shouldControl;
				if (shouldControl)
				{
					InitializeControl();
				}
				else
				{
					TeardownControl();
				}
			}
		}

		private void EnsureManualSuppression()
		{
			if (!aiSuppressed)
			{
				aiSuppressed = true;
				if ((Object)(object)aiLink != (Object)null)
				{
					((Behaviour)aiLink).enabled = false;
				}
				DisableGrandpaLogic();
			}
		}

		private void ReleaseManualSuppression()
		{
			if (aiSuppressed)
			{
				aiSuppressed = false;
				RestoreGrandpaLogic();
			}
		}

		private void InitializeControl()
		{
			//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_0073: Unknown result type (might be due to invalid IL or missing references)
			if (!initialized)
			{
				initialized = true;
				if (cameraFollowGnomeRoutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(cameraFollowGnomeRoutine);
					cameraFollowGnomeRoutine = null;
				}
				controlledPosition = ((Component)this).transform.position;
				nextActionTime = 0f;
				handDistance = 1.4f;
				verticalVelocity = 0f;
				cameraYaw = ((Component)this).transform.eulerAngles.y;
				cameraPitch = 0f;
				SetupCamera();
				SetupHiddenGnome(hide: true);
				StartForceStandRoutine();
				InitDebugUI();
			}
		}

		private void TeardownControl()
		{
			if (initialized)
			{
				initialized = false;
				if (standFixRoutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(standFixRoutine);
				}
				if ((Object)(object)localGnome == (Object)null)
				{
					localGnome = ServerManager.GetLocalPlayer();
				}
				SetupHiddenGnome(hide: false);
				RestoreCameraToOriginalState();
				RestoreCameraScripts();
				RestoreGrandpaLogic();
				if ((Object)(object)anim != (Object)null)
				{
					anim.SetFloat("InputMagnitude", 0f);
					anim.SetFloat("X", 0f);
					anim.SetFloat("Y", 0f);
					anim.SetFloat("Speed", 0f);
					TrySetAnimatorBool("Crouched", value: false);
				}
				Cursor.lockState = (CursorLockMode)1;
				Cursor.visible = false;
				if (cameraFollowGnomeRoutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(cameraFollowGnomeRoutine);
				}
				cameraFollowGnomeRoutine = ((MonoBehaviour)this).StartCoroutine(KeepCameraAttachedToGnome());
			}
		}

		private void RestoreCameraToOriginalState()
		{
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: 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)
			if ((Object)(object)localGnome == (Object)null)
			{
				localGnome = ServerManager.GetLocalPlayer();
			}
			if ((Object)(object)myCamera == (Object)null)
			{
				if ((Object)(object)localGnome != (Object)null)
				{
					myCamera = ((Component)localGnome).GetComponentInChildren<Camera>(true);
				}
				if ((Object)(object)myCamera == (Object)null)
				{
					myCamera = Camera.main ?? Object.FindAnyObjectByType<Camera>();
				}
			}
			if (!((Object)(object)myCamera == (Object)null) && !((Object)(object)localGnome == (Object)null))
			{
				Transform val = originalCameraParent;
				if ((Object)(object)val == (Object)null || !((Component)val).gameObject.activeInHierarchy)
				{
					val = FindGnomeCameraHolder(localGnome);
				}
				((Component)myCamera).transform.SetParent(val, false);
				if ((Object)(object)originalCameraParent == (Object)(object)val)
				{
					((Component)myCamera).transform.localPosition = originalCameraLocalPos;
					((Component)myCamera).transform.localRotation = originalCameraLocalRot;
				}
				else
				{
					((Component)myCamera).transform.localPosition = Vector3.zero;
					((Component)myCamera).transform.localRotation = Quaternion.identity;
				}
				((Behaviour)myCamera).enabled = true;
			}
		}

		private Transform FindGnomeCameraHolder(PlayerNetworking gnome)
		{
			if ((Object)(object)gnome == (Object)null)
			{
				return null;
			}
			Transform val = ((Component)gnome).transform.Find("Controller/CameraHolder") ?? ((Component)gnome).transform.Find("CameraHolder") ?? ((Component)gnome).transform.Find("CameraTarget") ?? ((Component)gnome).transform.Find("Head");
			if ((Object)(object)val != (Object)null)
			{
				return val;
			}
			Transform[] componentsInChildren = ((Component)gnome).GetComponentsInChildren<Transform>(true);
			foreach (Transform val2 in componentsInChildren)
			{
				string text = ((Object)val2).name.ToLowerInvariant();
				if (text.Contains("cameraholder") || text == "head" || text.Contains("cameratarget") || text.Contains("eyepos"))
				{
					return val2;
				}
			}
			return ((Component)gnome).transform;
		}

		private IEnumerator KeepCameraAttachedToGnome()
		{
			float timer = 0f;
			while (timer < 3f && !isControlledByMe)
			{
				if ((Object)(object)localGnome == (Object)null)
				{
					localGnome = ServerManager.GetLocalPlayer();
				}
				if ((Object)(object)myCamera == (Object)null)
				{
					if ((Object)(object)localGnome != (Object)null)
					{
						myCamera = ((Component)localGnome).GetComponentInChildren<Camera>(true);
					}
					if ((Object)(object)myCamera == (Object)null)
					{
						myCamera = Camera.main ?? Object.FindAnyObjectByType<Camera>();
					}
				}
				if ((Object)(object)localGnome != (Object)null && (Object)(object)myCamera != (Object)null)
				{
					Transform target = (((Object)(object)originalCameraParent != (Object)null && ((Component)originalCameraParent).gameObject.activeInHierarchy) ? originalCameraParent : FindGnomeCameraHolder(localGnome));
					if ((Object)(object)((Component)myCamera).transform.parent != (Object)(object)target)
					{
						((Component)myCamera).transform.SetParent(target, false);
						((Component)myCamera).transform.localPosition = (((Object)(object)originalCameraParent == (Object)(object)target) ? originalCameraLocalPos : Vector3.zero);
						((Component)myCamera).transform.localRotation = (((Object)(object)originalCameraParent == (Object)(object)target) ? originalCameraLocalRot : Quaternion.identity);
					}
					UnfreezeGnomeState(localGnome);
				}
				timer += 0.2f;
				yield return (object)new WaitForSeconds(0.2f);
			}
			cameraFollowGnomeRoutine = null;
		}

		private void UnfreezeGnomeState(PlayerNetworking gnome)
		{
			if ((Object)(object)gnome == (Object)null)
			{
				return;
			}
			CharacterController component = ((Component)gnome).GetComponent<CharacterController>();
			if ((Object)(object)component != (Object)null && !((Collider)component).enabled)
			{
				((Collider)component).enabled = true;
			}
			MonoBehaviour[] componentsInChildren = ((Component)gnome).GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if ((Object)(object)val != (Object)null && !((Behaviour)val).enabled)
				{
					string name = ((object)val).GetType().Name;
					if (name.Contains("PlayerController") || name.Contains("CharacterBrain") || name.Contains("HandController") || name.Contains("Movement"))
					{
						((Behaviour)val).enabled = true;
					}
				}
			}
			Type type = ((object)gnome).GetType();
			BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
			string[] array = new string[4] { "canMove", "allowMovement", "inputEnabled", "isGrounded" };
			string[] array2 = array;
			foreach (string name2 in array2)
			{
				FieldInfo field = type.GetField(name2, bindingAttr);
				if (field != null && field.FieldType == typeof(bool))
				{
					field.SetValue(gnome, true);
				}
			}
			string[] array3 = new string[6] { "isFrozen", "isGrabbed", "isRagdolled", "isDead", "isTied", "inputBlocked" };
			string[] array4 = array3;
			foreach (string name3 in array4)
			{
				FieldInfo field2 = type.GetField(name3, bindingAttr);
				if (field2 != null && field2.FieldType == typeof(bool))
				{
					field2.SetValue(gnome, false);
				}
			}
			try
			{
				((GameEntityBase)gnome).ApplyEffect((EffectType)3, 0f);
			}
			catch
			{
			}
		}

		private void DisableGrandpaLogic()
		{
			//IL_015f: 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_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)aiLink != (Object)null)
			{
				aiLink.disablePOILook = true;
				FollowerEntity component = ((Component)this).GetComponent<FollowerEntity>();
				if ((Object)(object)component != (Object)null)
				{
					component.isStopped = true;
				}
			}
			MonoBehaviour[] componentsInChildren = ((Component)this).GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)this) && ((Behaviour)val).enabled)
				{
					string text = ((object)val).GetType().Name.ToLowerInvariant();
					if (text.Contains("ai") || text.Contains("behaviourtree") || text.Contains("nav") || text.Contains("fsm") || text.Contains("humanmecanim"))
					{
						disabledGrandpaScripts.Add(val);
						((Behaviour)val).enabled = false;
					}
				}
			}
			Rigidbody component2 = ((Component)this).GetComponent<Rigidbody>();
			if ((Object)(object)component2 != (Object)null)
			{
				modifiedGrandpaBodies.Add(new BodyState
				{
					Rb = component2,
					WasKinematic = component2.isKinematic,
					HadGravity = component2.useGravity,
					HadDetectCollisions = component2.detectCollisions,
					Constraints = component2.constraints
				});
				if (!component2.isKinematic)
				{
					component2.linearVelocity = Vector3.zero;
					component2.angularVelocity = Vector3.zero;
				}
				component2.isKinematic = true;
			}
		}

		private void RestoreGrandpaLogic()
		{
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)aiLink != (Object)null)
			{
				aiLink.disablePOILook = false;
				FollowerEntity component = ((Component)this).GetComponent<FollowerEntity>();
				if ((Object)(object)component != (Object)null)
				{
					component.isStopped = false;
				}
			}
			foreach (MonoBehaviour disabledGrandpaScript in disabledGrandpaScripts)
			{
				if ((Object)(object)disabledGrandpaScript != (Object)null)
				{
					((Behaviour)disabledGrandpaScript).enabled = true;
				}
			}
			disabledGrandpaScripts.Clear();
			foreach (BodyState modifiedGrandpaBody in modifiedGrandpaBodies)
			{
				if ((Object)(object)modifiedGrandpaBody.Rb != (Object)null)
				{
					modifiedGrandpaBody.Rb.isKinematic = modifiedGrandpaBody.WasKinematic;
					modifiedGrandpaBody.Rb.useGravity = modifiedGrandpaBody.HadGravity;
					modifiedGrandpaBody.Rb.detectCollisions = modifiedGrandpaBody.HadDetectCollisions;
					modifiedGrandpaBody.Rb.constraints = modifiedGrandpaBody.Constraints;
				}
			}
			modifiedGrandpaBodies.Clear();
			if ((Object)(object)aiLink != (Object)null)
			{
				((Behaviour)aiLink).enabled = true;
			}
		}

		private void StartForceStandRoutine()
		{
			if (standFixRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(standFixRoutine);
			}
			standFixRoutine = ((MonoBehaviour)this).StartCoroutine(ForceStandRoutine());
		}

		private IEnumerator ForceStandRoutine()
		{
			for (int i = 0; i < 5; i++)
			{
				((Component)this).transform.rotation = Quaternion.Euler(0f, ((Component)this).transform.eulerAngles.y, 0f);
				controlledPosition = ((Component)this).transform.position;
				GrandpaModPatches.ForceWakeGrandpaAnimator(aiLink);
				if ((Object)(object)anim != (Object)null)
				{
					anim.Rebind();
					anim.SetFloat("InputMagnitude", 0f);
					anim.SetFloat("Speed", 0f);
					TrySetAnimatorBool("Sleeping", value: false);
					TrySetAnimatorBool("InBed", value: false);
					TrySetAnimatorBool("Lying", value: false);
					TrySetAnimatorBool("Crouched", value: false);
					anim.Play("Idle", 0);
				}
				if ((Object)(object)aiLink != (Object)null)
				{
					TryInvokeNoArg(aiLink, "ExitBed");
					TryInvokeNoArg(aiLink, "LeaveBed");
				}
				yield return (object)new WaitForSeconds(0.1f);
			}
			standFixRoutine = null;
		}

		private void SetupHiddenGnome(bool hide)
		{
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Expected O, but got Unknown
			//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Expected O, but got Unknown
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_047a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0492: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ae: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)localGnome == (Object)null)
			{
				localGnome = ServerManager.GetLocalPlayer();
			}
			if ((Object)(object)localGnome == (Object)null)
			{
				return;
			}
			Transform root = ((Component)localGnome).transform.root;
			if (hide)
			{
				MonoBehaviour[] componentsInChildren = ((Component)localGnome).GetComponentsInChildren<MonoBehaviour>(true);
				foreach (MonoBehaviour val in componentsInChildren)
				{
					if ((Object)(object)val != (Object)null && ((Behaviour)val).enabled)
					{
						string name = ((object)val).GetType().Name;
						if (name.Contains("PlayerController") || name.Contains("CharacterBrain") || name.Contains("HandController") || name == "PlayerHud")
						{
							disabledGnomeScripts.Add(val);
							((Behaviour)val).enabled = false;
						}
					}
				}
				Rigidbody[] componentsInChildren2 = ((Component)localGnome).GetComponentsInChildren<Rigidbody>();
				foreach (Rigidbody val2 in componentsInChildren2)
				{
					if (!val2.isKinematic)
					{
						frozenGnomeBodies.Add(val2);
						val2.isKinematic = true;
					}
				}
				if (forceHideUIRoutine != null)
				{
					((MonoBehaviour)this).StopCoroutine(forceHideUIRoutine);
				}
				forceHideUIRoutine = ((MonoBehaviour)this).StartCoroutine(ForceHideUIDeepSeekRoutine(root));
				if ((Object)(object)grandpaCrosshairCanvas == (Object)null)
				{
					grandpaCrosshairCanvas = new GameObject("GrandpaCrosshairCanvas");
					Canvas val3 = grandpaCrosshairCanvas.AddComponent<Canvas>();
					val3.renderMode = (RenderMode)0;
					val3.sortingOrder = 100;
					CanvasScaler val4 = grandpaCrosshairCanvas.AddComponent<CanvasScaler>();
					val4.uiScaleMode = (ScaleMode)1;
					GameObject val5 = new GameObject("DotText");
					val5.transform.SetParent(grandpaCrosshairCanvas.transform, false);
					Text val6 = val5.AddComponent<Text>();
					val6.text = "•";
					val6.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
					val6.fontSize = 24;
					((Graphic)val6).color = new Color(1f, 1f, 1f, 0.7f);
					val6.alignment = (TextAnchor)4;
					RectTransform component = val5.GetComponent<RectTransform>();
					component.anchoredPosition = Vector2.zero;
					component.sizeDelta = new Vector2(50f, 50f);
				}
				grandpaCrosshairCanvas.SetActive(true);
				return;
			}
			if (forceHideUIRoutine != null)
			{
				((MonoBehaviour)this).StopCoroutine(forceHideUIRoutine);
			}
			forceHideUIRoutine = null;
			foreach (Rigidbody frozenGnomeBody in frozenGnomeBodies)
			{
				if ((Object)(object)frozenGnomeBody != (Object)null)
				{
					frozenGnomeBody.isKinematic = false;
					frozenGnomeBody.detectCollisions = true;
					frozenGnomeBody.useGravity = true;
					frozenGnomeBody.constraints = (RigidbodyConstraints)112;
				}
			}
			frozenGnomeBodies.Clear();
			foreach (MonoBehaviour disabledGnomeScript in disabledGnomeScripts)
			{
				if ((Object)(object)disabledGnomeScript != (Object)null)
				{
					((Behaviour)disabledGnomeScript).enabled = true;
				}
			}
			disabledGnomeScripts.Clear();
			MonoBehaviour[] componentsInChildren3 = ((Component)localGnome).GetComponentsInChildren<MonoBehaviour>(true);
			foreach (MonoBehaviour val7 in componentsInChildren3)
			{
				if ((Object)(object)val7 != (Object)null)
				{
					((Behaviour)val7).enabled = true;
				}
			}
			UnfreezeGnomeState(localGnome);
			Transform val8 = root.Find("Canvas");
			if ((Object)(object)val8 != (Object)null)
			{
				Canvas component2 = ((Component)val8).GetComponent<Canvas>();
				if ((Object)(object)component2 != (Object)null)
				{
					((Behaviour)component2).enabled = true;
				}
			}
			Transform val9 = root.Find("Controller/UIDocument");
			if ((Object)(object)val9 != (Object)null)
			{
				UIDocument component3 = ((Component)val9).GetComponent<UIDocument>();
				if ((Object)(object)component3 != (Object)null)
				{
					((Behaviour)component3).enabled = true;
					if (component3.rootVisualElement != null)
					{
						component3.rootVisualElement.style.display = StyleEnum<DisplayStyle>.op_Implicit((DisplayStyle)0);
						component3.rootVisualElement.style.visibility = StyleEnum<Visibility>.op_Implicit((Visibility)0);
						component3.rootVisualElement.style.opacity = StyleFloat.op_Implicit(1f);
						component3.rootVisualElement.MarkDirtyRepaint();
					}
				}
			}
			if ((Object)(object)grandpaCrosshairCanvas != (Object)null)
			{
				grandpaCrosshairCanvas.SetActive(false);
			}
		}

		private IEnumerator ForceHideUIDeepSeekRoutine(Transform root)
		{
			while (isControlledByMe && (Object)(object)localGnome != (Object)null && (Object)(object)root != (Object)null)
			{
				Transform canvasTrans = root.Find("Canvas");
				if ((Object)(object)canvasTrans != (Object)null)
				{
					Canvas canvas = ((Component)canvasTrans).GetComponent<Canvas>();
					if ((Object)(object)canvas != (Object)null && ((Behaviour)canvas).enabled)
					{
						((Behaviour)canvas).enabled = false;
					}
				}
				Transform uiDocTrans = root.Find("Controller/UIDocument");
				if ((Object)(object)uiDocTrans != (Object)null)
				{
					UIDocument doc = ((Component)uiDocTrans).GetComponent<UIDocument>();
					if ((Object)(object)doc != (Object)null && doc.rootVisualElement != null)
					{
						VisualElement rootElem = doc.rootVisualElement;
						rootElem.style.display = StyleEnum<DisplayStyle>.op_Implicit((DisplayStyle)1);
						rootElem.style.visibility = StyleEnum<Visibility>.op_Implicit((Visibility)1);
						rootElem.style.opacity = StyleFloat.op_Implicit(0f);
						rootElem.MarkDirtyRepaint();
					}
				}
				yield return null;
			}
		}

		private void TrySetAnimatorBool(string name, bool value)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between Unknown and I4
			if (!((Object)(object)anim != (Object)null))
			{
				return;
			}
			AnimatorControllerParameter[] parameters = anim.parameters;
			foreach (AnimatorControllerParameter val in parameters)
			{
				if ((int)val.type == 4 && val.name == name)
				{
					anim.SetBool(name, value);
					break;
				}
			}
		}

		private static void TryInvokeNoArg(object target, string methodName)
		{
			if (target == null)
			{
				return;
			}
			try
			{
				target.GetType().GetMethod(methodName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.Invoke(target, null);
			}
			catch
			{
			}
		}

		private void InitDebugUI()
		{
		}

		private void UpdateDebugMenu()
		{
			//IL_03da: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ea: Unknown result type (might be due to invalid IL or missing references)
			if (Input.GetKeyDown((KeyCode)106))
			{
				showDebugMenu = !showDebugMenu;
				Debug.Log((object)("[Grandpa Debug] J pressed, showDebugMenu = " + showDebugMenu));
			}
			if (!showDebugMenu || !isControlledByMe)
			{
				return;
			}
			if (Input.GetKeyDown((KeyCode)107))
			{
				string text = (GUIUtility.systemCopyBuffer = $"targetPos = new Vector3({debugWeaponPos.x:F3}f, {debugWeaponPos.y:F3}f, {debugWeaponPos.z:F3}f);\n" + $"targetRot = new Vector3({debugWeaponRot.x:F1}f, {debugWeaponRot.y:F1}f, {debugWeaponRot.z:F1}f);");
				Debug.Log((object)("[Grandpa Debug] COPIED TO CLIPBOARD:\n" + text));
			}
			if (Input.GetKeyDown((KeyCode)304))
			{
				debugMode = ((debugMode == "POS") ? "ROT" : "POS");
			}
			float num = 0.3f * Time.deltaTime;
			float num2 = 60f * Time.deltaTime;
			if (Input.GetKey((KeyCode)306))
			{
				num *= 0.1f;
				num2 *= 0.2f;
			}
			bool flag = false;
			if (debugMode == "POS")
			{
				if (Input.GetKey((KeyCode)264))
				{
					debugWeaponPos.z += num;
					flag = true;
				}
				if (Input.GetKey((KeyCode)258))
				{
					debugWeaponPos.z -= num;
					flag = true;
				}
				if (Input.GetKey((KeyCode)260))
				{
					debugWeaponPos.x -= num;
					flag = true;
				}
				if (Input.GetKey((KeyCode)262))
				{
					debugWeaponPos.x += num;
					flag = true;
				}
				if (Input.GetKey((KeyCode)263))
				{
					debugWeaponPos.y += num;
					flag = true;
				}
				if (Input.GetKey((KeyCode)265))
				{
					debugWeaponPos.y -= num;
					flag = true;
				}
			}
			else
			{
				if (Input.GetKey((KeyCode)264))
				{
					debugWeaponRot.x += num2;
					flag = true;
				}
				if (Input.GetKey((KeyCode)258))
				{
					debugWeaponRot.x -= num2;
					flag = true;
				}
				if (Input.GetKey((KeyCode)260))
				{
					debugWeaponRot.y -= num2;
					flag = true;
				}
				if (Input.GetKey((KeyCode)262))
				{
					debugWeaponRot.y += num2;
					flag = true;
				}
				if (Input.GetKey((KeyCode)263))
				{
					debugWeaponRot.z += num2;
					flag = true;
				}
				if (Input.GetKey((KeyCode)265))
				{
					debugWeaponRot.z -= num2;
					flag = true;
				}
			}
			if (flag)
			{
				Debug.Log((object)$"[Grandpa Debug] POS: X={debugWeaponPos.x:F3} Y={debugWeaponPos.y:F3} Z={debugWeaponPos.z:F3} | ROT: X={debugWeaponRot.x:F1} Y={debugWeaponRot.y:F1} Z={debugWeaponRot.z:F1}");
				SendAction(6, 0uL, debugWeaponPos);
				SendAction(7, 0uL, debugWeaponRot);
			}
		}

		private void OnGUI()
		{
			//IL_0034: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Expected O, but got Unknown
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: 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_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c7: 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)
			if (showDebugMenu && isControlledByMe)
			{
				GUI.Box(new Rect(10f, 10f, 750f, 190f), "WEAPON POSITION DEBUGGER (Press J to hide)");
				GUIStyle val = new GUIStyle(GUI.skin.label)
				{
					fontSize = 15,
					fontStyle = (FontStyle)1,
					wordWrap = false
				};
				val.normal.textColor = Color.yellow;
				string text = "MODE: [" + debugMode + "] (Left Shift to toggle) | Press [K] to COPY code to clipboard";
				string text2 = "Hold [LCtrl] for fine/slow adjustments";
				string text3 = $"POS (Numpad 8/2/4/6/7/9):   X: {debugWeaponPos.x:F3}   |   Y: {debugWeaponPos.y:F3}   |   Z: {debugWeaponPos.z:F3}";
				string text4 = $"ROT (Numpad 8/2/4/6/7/9):   X: {debugWeaponRot.x:F1}°  |  Y: {debugWeaponRot.y:F1}°  |  Z: {debugWeaponRot.z:F1}°";
				GUI.Label(new Rect(20f, 35f, 720f, 25f), text, val);
				val.normal.textColor = Color.white;
				GUI.Label(new Rect(20f, 65f, 720f, 25f), text2, val);
				val.normal.textColor = ((debugMode == "POS") ? Color.green : Color.gray);
				GUI.Label(new Rect(20f, 100f, 720f, 30f), text3, val);
				val.normal.textColor = ((debugMode == "ROT") ? Color.green : Color.gray);
				GUI.Label(new Rect(20f, 135f, 720f, 30f), text4, val);
			}
		}

		private void HandleMovement(bool isCrouching)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: 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_0128: 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_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: 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_015e: 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_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0332: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_0329: 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_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_034c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_0353: Unknown result type (might be due to invalid IL or missing references)
			//IL_0358: Unknown result type (might be due to invalid IL or missing references)
			//IL_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_035d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Unknown result type (might be due to invalid IL or missing references)
			//IL_0365: Unknown result type (might be due to invalid IL or missing references)
			//IL_0367: 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_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			if (isCrouching != wasCrouching)
			{
				wasCrouching = isCrouching;
				crouchLockEndTime = Time.time + 4f;
			}
			bool flag = false;
			if ((Object)(object)anim != (Object)null)
			{
				AnimatorStateInfo currentAnimatorStateInfo = anim.GetCurrentAnimatorStateInfo(0);
				AnimatorStateInfo nextAnimatorStateInfo = anim.GetNextAnimatorStateInfo(0);
				string text = ((((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Crouch") || ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Crouched") || ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Stand") || ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("StandUp")) ? ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash.ToString() : "");
				if (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Crouch") || ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("Stand") || ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).IsName("StandUp") || ((AnimatorStateInfo)(ref nextAnimatorStateInfo)).IsName("Crouch") || ((AnimatorStateInfo)(ref nextAnimatorStateInfo)).IsName("Stand") || ((AnimatorStateInfo)(ref nextAnimatorStateInfo)).IsName("StandUp"))
				{
					flag = true;
				}
			}
			bool flag2 = isCrouching || Time.time < crouchLockEndTime || flag;
			Vector3 val = Vector3.zero;
			float num = 0f;
			float num2 = 0f;
			if (!flag2)
			{
				if (Input.GetKey((KeyCode)119))
				{
					val += ((Component)this).transform.forward;
					num2 += 1f;
				}
				if (Input.GetKey((KeyCode)115))
				{
					val -= ((Component)this).transform.forward;
					num2 -= 1f;
				}
				if (Input.GetKey((KeyCode)97))
				{
					val -= ((Component)this).transform.right;
					num -= 1f;
				}
				if (Input.GetKey((KeyCode)100))
				{
					val += ((Component)this).transform.right;
					num += 1f;
				}
			}
			Vector2 val2 = new Vector2(num, num2);
			lastMoveInputMagnitude = Mathf.Clamp01(((Vector2)(ref val2)).magnitude);
			if (lastMoveInputMagnitude < 0.05f || flag2)
			{
				num = 0f;
				num2 = 0f;
				lastMoveInputMagnitude = 0f;
				if ((Object)(object)anim != (Object)null)
				{
					anim.SetFloat("InputMagnitude", 0f);
					anim.SetFloat("X", 0f);
					anim.SetFloat("Y", 0f);
					anim.SetFloat("Speed", 0f);
				}
			}
			else if ((Object)(object)anim != (Object)null)
			{
				anim.SetFloat("InputMagnitude", lastMoveInputMagnitude);
				anim.SetFloat("X", num);
				anim.SetFloat("Y", num2);
				anim.SetFloat("Speed", lastMoveInputMagnitude);
			}
			float num3 = 8.05f;
			Vector3 delta = ((lastMoveInputMagnitude > 0f) ? (((Vector3)(ref val)).normalized * num3 * Time.deltaTime) : Vector3.zero);
			Vector3 pos = ResolveCollision(controlledPosition, delta);
			pos = ApplyGravityAndSnapToGround(pos);
			controlledPosition = pos;
			((Component)this).transform.position = controlledPosition;
			if ((Object)(object)anim != (Object)null && (Object)(object)aiLink != (Object)null && (Object)(object)aiLink.kidnapper != (Object)null)
			{
				anim.SetBool("Carrying", (Object)(object)aiLink.kidnapper.CurrentlyHeld != (Object)null);
			}
		}

		private Vector3 ResolveCollision(Vector3 start, Vector3 delta)
		{
			//IL_001c: 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_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_004d: 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_0031: 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_0065: 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_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			if (((Vector3)(ref delta)).magnitude <= 0.0001f)
			{
				return start;
			}
			if (TryCapsuleMove(start, delta, 0.32f, out var result))
			{
				return result;
			}
			Vector3 start2 = start + Vector3.up * 1.5f;
			if (TryCapsuleMove(start2, delta, 1.5f, out var result2))
			{
				return result2;
			}
			return result;
		}

		private bool TryCapsuleMove(Vector3 start, Vector3 delta, float bottomOffset, out Vector3 result)
		{
			//IL_002b: 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_0033: 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_003a: 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_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_007f: 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_0086: 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_001e: 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_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_0136: 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_014e: 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)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			float magnitude = ((Vector3)(ref delta)).magnitude;
			if (magnitude <= 0.0001f)
			{
				result = start;
				return true;
			}
			Vector3 val = delta / magnitude;
			Vector3 val2 = start + Vector3.up * bottomOffset;
			Vector3 val3 = start + Vector3.up * 1.59f;
			bool flag = false;
			float num = magnitude;
			int num2 = ~LayerMask.GetMask(new string[2] { "Ignore Raycast", "Player" });
			RaycastHit[] array = Physics.CapsuleCastAll(val2, val3, 0.63f, val, magnitude + 0.1f, num2, (QueryTriggerInteraction)1);
			RaycastHit[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				RaycastHit val4 = array2[i];
				if ((Object)(object)((RaycastHit)(ref val4)).collider != (Object)null && !((RaycastHit)(ref val4)).collider.isTrigger && (Object)(object)((Component)((RaycastHit)(ref val4)).collider).transform.root != (Object)(object)((Component)this).transform.root)
				{
					flag = true;
					if (((RaycastHit)(ref val4)).distance < num)
					{
						num = ((RaycastHit)(ref val4)).distance;
					}
				}
			}
			result = (flag ? (start + val * Mathf.Max(0f, num - 0.1f)) : (start + delta));
			return !flag;
		}

		private Vector3 ApplyGravityAndSnapToGround(Vector3 pos)
		{
			//IL_0001: 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_0025: 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_004f: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			float y = pos.y;
			float num = float.MaxValue;
			float? num2 = null;
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(pos.x, y + 2f, pos.z);
			int num3 = ~LayerMask.GetMask(new string[2] { "Ignore Raycast", "Player" });
			RaycastHit[] array = Physics.RaycastAll(val, Vector3.down, 10f, num3, (QueryTriggerInteraction)1);
			RaycastHit[] array2 = array;
			for (int i = 0; i < array2.Length; i++)
			{
				RaycastHit val2 = array2[i];
				if ((Object)(object)((RaycastHit)(ref val2)).collider != (Object)null && (Object)(object)((Component)((RaycastHit)(ref val2)).collider).transform.root != (Object)(object)((Component)this).transform.root && !((RaycastHit)(ref val2)).collider.isTrigger && ((RaycastHit)(ref val2)).distance < num)
				{
					num = ((RaycastHit)(ref val2)).distance;
					num2 = ((RaycastHit)(ref val2)).point.y;
				}
			}
			if (num2.HasValue)
			{
				if (num2.Value <= y + 1.5f && num2.Value >= y - 4f)
				{
					pos.y = num2.Value;
					verticalVelocity = 0f;
				}
				else
				{
					verticalVelocity -= 20f * Time.deltaTime;
					pos.y += verticalVelocity * Time.deltaTime;
				}
			}
			else
			{
				verticalVelocity -= 20f * Time.deltaTime;
				pos.y += verticalVelocity * Time.deltaTime;
			}
			return pos;
		}
	}
	internal static class GrandpaModPatches
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static HandleNamedMessageDelegate <0>__OnGrandpaChosenReceived;

			public static HandleNamedMessageDelegate <1>__OnGrandpaActionReceived;
		}

		public static ulong chosenGrandpaClientId = ulong.MaxValue;

		public static bool handlersRegistered = false;

		[HarmonyPatch(typeof(GameProgressionManager), "OnNetworkSpawn")]
		[HarmonyPostfix]
		private static void OnNetworkSpawnPostfix(GameProgressionManager __instance)
		{
			RegisterHandlersSafe();
		}

		[HarmonyPatch(typeof(GameProgressionManager), "OnNetworkDespawn")]
		[HarmonyPostfix]
		private static void OnNetworkDespawnPostfix(GameProgressionManager __instance)
		{
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.CustomMessagingManager != null && handlersRegistered)
			{
				CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
				customMessagingManager.UnregisterNamedMessageHandler("GrandpaChosenMessage");
				if (NetworkManager.Singleton.IsServer)
				{
					customMessagingManager.UnregisterNamedMessageHandler("GrandpaActionMsg");
				}
			}
			handlersRegistered = false;
			ApplyLocalControlState(ulong.MaxValue);
			chosenGrandpaClientId = ulong.MaxValue;
		}

		[HarmonyPatch(typeof(GameProgressionManager), "EndGame")]
		[HarmonyPrefix]
		private static void EndGamePrefix()
		{
			if (chosenGrandpaClientId != ulong.MaxValue)
			{
				Debug.Log((object)"[GrandpaMod] Игра окончена! Экстренный возврат на остров гнома...");
				ApplyLocalControlState(ulong.MaxValue);
				chosenGrandpaClientId = ulong.MaxValue;
			}
		}

		public static void RegisterHandlersSafe()
		{
			//IL_0052: 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_005d: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			if (handlersRegistered || !((Object)(object)NetworkManager.Singleton != (Object)null) || NetworkManager.Singleton.CustomMessagingManager == null)
			{
				return;
			}
			CustomMessagingManager customMessagingManager = NetworkManager.Singleton.CustomMessagingManager;
			object obj = <>O.<0>__OnGrandpaChosenReceived;
			if (obj == null)
			{
				HandleNamedMessageDelegate val = OnGrandpaChosenReceived;
				<>O.<0>__OnGrandpaChosenReceived = val;
				obj = (object)val;
			}
			customMessagingManager.RegisterNamedMessageHandler("GrandpaChosenMessage", (HandleNamedMessageDelegate)obj);
			if (NetworkManager.Singleton.IsServer)
			{
				object obj2 = <>O.<1>__OnGrandpaActionReceived;
				if (obj2 == null)
				{
					HandleNamedMessageDelegate val2 = OnGrandpaActionReceived;
					<>O.<1>__OnGrandpaActionReceived = val2;
					obj2 = (object)val2;
				}
				customMessagingManager.RegisterNamedMessageHandler("GrandpaActionMsg", (HandleNamedMessageDelegate)obj2);
			}
			handlersRegistered = true;
		}

		private static void OnGrandpaChosenReceived(ulong senderClientId, FastBufferReader messagePayload)
		{
			//IL_0014: 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)
			if (((FastBufferReader)(ref messagePayload)).TryBeginRead(8))
			{
				ulong selectedClientId = default(ulong);
				((FastBufferReader)(ref messagePayload)).ReadValueSafe<ulong>(ref selectedClientId, default(ForPrimitives));
				chosenGrandpaClientId = selectedClientId;
				ApplyLocalControlState(selectedClientId);
			}
		}

		private static void OnGrandpaActionReceived(ulong senderClientId, FastBufferReader messagePayload)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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_0062: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer && ((FastBufferReader)(ref messagePayload)).TryBeginRead(21))
			{
				byte actionId = default(byte);
				((FastBufferReader)(ref messagePayload)).ReadValueSafe<byte>(ref actionId, default(ForPrimitives));
				ulong targetId = default(ulong);
				((FastBufferReader)(ref messagePayload)).ReadValueSafe<ulong>(ref targetId, default(ForPrimitives));
				Vector3 dir = default(Vector3);
				((FastBufferReader)(ref messagePayload)).ReadValueSafe(ref dir);
				ExecuteGrandpaAction(actionId, targetId, dir);
			}
		}

		private static PlayerNetworking FindPlayerByClientId(ulong clientId)
		{
			PlayerNetworking[] array = Object.FindObjectsByType<PlayerNetworking>((FindObjectsInactive)0, (FindObjectsSortMode)0);
			PlayerNetworking[] array2 = array;
			foreach (PlayerNetworking val in array2)
			{
				if ((Object)(object)val != (Object)null && ((NetworkBehaviour)val).OwnerClientId == clientId)
				{
					return val;
				}
			}
			return null;
		}

		internal static void ExecuteGrandpaAction(byte actionId, ulong targetId, Vector3 dir = default(Vector3))
		{
			//IL_04f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0503: 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_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0510: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_039e: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: 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_03bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_0279: Unknown result type (might be due to invalid IL or missing references)
			HumanAILink val = Object.FindAnyObjectByType<HumanAILink>();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			CustomGrandpaController component = ((Component)val).GetComponent<CustomGrandpaController>();
			if ((Object)(object)component != (Object)null)
			{
				switch (actionId)
				{
				case 6:
					component.debugWeaponPos = dir;
					return;
				case 7:
					component.debugWeaponRot = dir;
					return;
				}
			}
			switch (actionId)
			{
			case 0:
			{
				if ((Object)(object)val.kidnapper == (Object)null || (Object)(object)val.kidnapper.CurrentlyHeld != (Object)null || (Object)(object)val.ObjectInHand != (Object)null)
				{
					break;
				}
				PlayerNetworking val2 = FindPlayerByClientId(targetId);
				if (!((Object)(object)val2 == (Object)null) && !((GameEntityBase)val2).IsDead && !((GameEntityBase)val2).IsGrabbed)
				{
					val.canPickupPlayers = true;
					((GameEntityAI)val).TargetedEntityInVision = (GameEntityBase)(object)val2;
					val.OnPlayerHitHandTrigger((GameEntityBase)(object)val2);
					if ((Object)(object)val.kidnapper.CurrentlyHeld == (Object)null)
					{
						val.kidnapper.CurrentlyHeld = (GameEntityBase)(object)val2;
					}
					val.ApplyEffectToCarriedPlayer(false, 0f);
					val2.ForceRagdoll();
					if ((Object)(object)((GameEntityBase)val).NAnimator != (Object)null)
					{
						((GameEntityBase)val).NAnimator.SetTrigger("Grab");
						((GameEntityBase)val).NAnimator.Animator.SetBool("Carrying", true);
					}
					TrySendCaughtEvent(val);
				}
				break;
			}
			case 1:
				if ((Object)(object)val.kidnapper != (Object)null && (Object)(object)val.kidnapper.CurrentlyHeld != (Object)null)
				{
					val.kidnapper.CurrentlyHeld.ApplyEffect((EffectType)3, 0f);
					val.kidnapper.AnticipateLocalPlayerRemoval();
					val.kidnapper.CurrentlyHeld = null;
					if ((Object)(object)((GameEntityBase)val).NAnimator != (Object)null)
					{
						((GameEntityBase)val).NAnimator.Animator.SetBool("Carrying", false);
					}
				}
				break;
			case 2:
			{
				if (!((Object)(object)val.ObjectInHand != (Object)null))
				{
					break;
				}
				Gun component3 = ((Component)val.ObjectInHand).GetComponent<Gun>();
				if ((Object)(object)component3 != (Object)null && component3.HasBullets)
				{
					Vector3 val3 = ((dir != Vector3.zero) ? dir : ((Component)val).transform.forward);
					component3.DoShoot(val3, true);
				}
				else
				{
					Chainsaw component4 = ((Component)val.ObjectInHand).GetComponent<Chainsaw>();
					if ((Object)(object)component4 != (Object)null)
					{
						ToggleViaReflection(component4);
					}
					else
					{
						Component component5 = ((Component)val.ObjectInHand).GetComponent("Leafblower");
						if ((Object)(object)component5 != (Object)null)
						{
							ToggleViaReflection(component5);
						}
						else
						{
							ToggleableNetworkBehaviour component6 = ((Component)val.ObjectInHand).GetComponent<ToggleableNetworkBehaviour>();
							if ((Object)(object)component6 != (Object)null)
							{
								ToggleViaReflection(component6);
							}
							else
							{
								ToggleableInteractable componentInChildren = ((Component)val.ObjectInHand).GetComponentInChildren<ToggleableInteractable>();
								if ((Object)(object)componentInChildren != (Object)null)
								{
									componentInChildren.ToggleRpc();
								}
							}
						}
					}
				}
				val.DoUseHeldItem();
				break;
			}
			case 3:
				if ((Object)(object)val.kidnapper != (Object)null && (Object)(object)val.kidnapper.CurrentlyHeld != (Object)null)
				{
					GameEntityBase currentlyHeld = val.kidnapper.CurrentlyHeld;
					PlayerNetworking gnome = (PlayerNetworking)(object)((currentlyHeld is PlayerNetworking) ? currentlyHeld : null);
					val.kidnapper.AnticipateLocalPlayerRemoval();
					val.kidnapper.CurrentlyHeld = null;
					Vector3 vel = dir * 25f + Vector3.up * 5f;
					((MonoBehaviour)val).StartCoroutine(DelayedThrowGnome(gnome, currentlyHeld, vel));
					if ((Object)(object)((GameEntityBase)val).NAnimator != (Object)null)
					{
						((GameEntityBase)val).NAnimator.SetTrigger("Throw");
						((GameEntityBase)val).NAnimator.Animator.SetBool("Carrying", false);
					}
				}
				break;
			case 4:
			{
				if (!((Object)(object)val.ObjectInHand != (Object)null))
				{
					break;
				}
				StealableObject objectInHand = val.ObjectInHand;
				try
				{
					((GameEntityAI)val).TargetedEntityInVision = null;
					FieldInfo field2 = typeof(HumanAILink).GetField("blackboard", BindingFlags.Instance | BindingFlags.NonPublic);
					if (field2 != null)
					{
						object value3 = field2.GetValue(val);
						if (value3 != null)
						{
							MethodInfo method2 = value3.GetType().GetMethod("SetVariableValue", new Type[2]
							{
								typeof(string),
								typeof(object)
							});
							if (method2 != null)
							{
								method2.Invoke(value3, new object[2] { "objectToPickup", null });
							}
						}
					}
				}
				catch
				{
				}
				val.ReleaseObject();
				Vector3 dir2 = ((dir != Vector3.zero) ? dir : ((Component)val).transform.forward);
				((MonoBehaviour)val).StartCoroutine(DelayedDropWeapon(objectInHand, dir2));
				if ((Object)(object)((GameEntityBase)val).NAnimator != (Object)null)
				{
					((GameEntityBase)val).NAnimator.SetTrigger("Throw");
				}
				break;
			}
			case 5:
			{
				if (!((Object)(object)val.ObjectInHand == (Object)null) || !((Object)(object)val.kidnapper.CurrentlyHeld == (Object)null) || !NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(targetId, out var value))
				{
					break;
				}
				StealableObject component2 = ((Component)value).GetComponent<StealableObject>();
				if (!((Object)(object)component2 != (Object)null))
				{
					break;
				}
				try
				{
					FieldInfo field = typeof(HumanAILink).GetField("blackboard", BindingFlags.Instance | BindingFlags.NonPublic);
					if (field != null)
					{
						object value2 = field.GetValue(val);
						if (value2 != null)
						{
							MethodInfo method = value2.GetType().GetMethod("SetVariableValue", new Type[2]
							{
								typeof(string),
								typeof(object)
							});
							if (method != null)
							{
								method.Invoke(value2, new object[2] { "objectToPickup", component2 });
							}
						}
					}
				}
				catch
				{
				}
				val.DoPickupNow(component2);
				((MonoBehaviour)val).StartCoroutine(ForceHoldUnsupportedWeapon(val, component2));
				break;
			}
			}
		}

		private static void ToggleViaReflection(object obj)
		{
			if (obj == null)
			{
				return;
			}
			Type type = obj.GetType();
			MethodInfo method = type.GetMethod("ToggleRpc", BindingFlags.Instance | BindingFlags.Public);
			if (method == null)
			{
				method = type.GetMethod("Toggle", BindingFlags.Instance | BindingFlags.Public);
			}
			if (method != null)
			{
				method.Invoke(obj, null);
				return;
			}
			PropertyInfo property = type.GetProperty("IsOn", BindingFlags.Instance | BindingFlags.Public);
			if (property != null && property.CanWrite)
			{
				bool flag = (bool)property.GetValue(obj);
				property.SetValue(obj, !flag);
			}
		}

		private static IEnumerator DelayedThrowGnome(PlayerNetworking gnome, GameEntityBase held, Vector3 vel)
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			yield return (object)new WaitForSeconds(0.1f);
			if ((Object)(object)gnome != (Object)null)
			{
				((GameEntityBase)gnome).AddVelocityRpc(vel);
			}
			else if ((Object)(object)held != (Object)null)
			{
				held.OnReceiveVelocity(vel);
			}
		}

		private static IEnumerator DelayedDropWeapon(StealableObject weapon, Vector3 dir)
		{
			//IL_000e: 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)
			yield return (object)new WaitForSeconds(0.1f);
			if ((Object)(object)weapon != (Object)null)
			{
				AttachableNetworkTransform attach = ((Component)weapon).GetComponent<AttachableNetworkTransform>();
				if ((Object)(object)attach != (Object)null)
				{
					attach.UnsetAttach();
				}
				((Component)weapon).transform.parent = null;
				if ((Object)(object)weapon.Rb != (Object)null)
				{
					weapon.Rb.isKinematic = false;
					weapon.Rb.useGravity = true;
					weapon.Rb.AddForce(dir * 6f, (ForceMode)1);
				}
			}
		}

		private static IEnumerator ForceHoldUnsupportedWeapon(HumanAILink ai, StealableObject weapon)
		{
			yield return null;
			if ((Object)(object)ai.ObjectInHand != (Object)(object)weapon)
			{
				yield break;
			}
			AttachableNetworkTransform attach = ((Component)weapon).GetComponent<AttachableNetworkTransform>();
			if ((Object)(object)attach != (Object)null && (Object)(object)attach.AttachedTo != (Object)null)
			{
				yield break;
			}
			Animator anim = ((Component)ai).GetComponentInChildren<Animator>();
			Transform rightHand = (((Object)(object)anim != (Object)null) ? anim.GetBoneTransform((HumanBodyBones)18) : ((Component)ai).transform);
			CustomGrandpaController ctrl = ((Component)ai).GetComponent<CustomGrandpaController>();
			if ((Object)(object)ctrl != (Object)null && ctrl.debugWeaponPos == Vector3.zero && ctrl.debugWeaponRot == Vector3.zero)
			{
				if ((int)weapon.ItemType == 6)
				{
					ctrl.debugWeaponPos = new Vector3(0.286f, 0.708f, -0.055f);
					ctrl.debugWeaponRot = new Vector3(100.1f, 174.2f, 166.5f);
				}
				else if ((int)weapon.ItemType == 94 || (Object)(object)((Component)weapon).GetComponent("Chainsaw") != (Object)null)
				{
					ctrl.debugWeaponPos = new Vector3(0.045f, 0.879f, -1.736f);
					ctrl.debugWeaponRot = new Vector3(282.3f, 178.1f, 4.2f);
				}
				else if ((int)weapon.ItemType == 96 || (Object)(object)((Component)weapon).GetComponent("Leafblower") != (Object)null)
				{
					ctrl.debugWeaponPos = new Vector3(-0.319f, -0.287f, -1.676f);
					ctrl.debugWeaponRot = new Vector3(349.9f, 475.9f, 48.1f);
				}
				else
				{
					ctrl.debugWeaponPos = new Vector3(0f, 0.5f, 0f);
					ctrl.debugWeaponRot = Vector3.zero;
				}
			}
			((Component)weapon).transform.parent = rightHand;
			while ((Object)(object)ai.ObjectInHand == (Object)(object)weapon)
			{
				Vector3 curPos = (Vector3)(((Object)(object)ctrl != (Object)null && ctrl.debugWeaponPos != Vector3.zero) ? ctrl.debugWeaponPos : new Vector3(-0.319f, -0.287f, -1.676f));
				Vector3 curRot = (Vector3)(((Object)(object)ctrl != (Object)null && ctrl.debugWeaponRot != Vector3.zero) ? ctrl.debugWeaponRot : new Vector3(349.9f, 475.9f, 48.1f));
				if ((int)weapon.ItemType == 6 && (Object)(object)ctrl != (Object)null && ctrl.debugWeaponPos == Vector3.zero)
				{
					curPos = new Vector3(0.286f, 0.708f, -0.055f);
					curRot = new Vector3(100.1f, 174.2f, 166.5f);
				}
				else if (((int)weapon.ItemType == 94 || (Object)(object)((Component)weapon).GetComponent("Chainsaw") != (Object)null) && (Object)(object)ctrl != (Object)null && ctrl.debugWeaponPos == Vector3.zero)
				{
					curPos = new Vector3(0.045f, 0.879f, -1.736f);
					curRot = new Vector3(282.3f, 178.1f, 4.2f);
				}
				weapon.Rb.isKinematic = true;
				((Component)weapon).transform.position = rightHand.position + rightHand.TransformDirection(curPos);
				((Component)weapon).transform.rotation = rightHand.rotation * Quaternion.Euler(curRot);
				weapon.Rb.position = ((Component)weapon).transform.position;
				weapon.Rb.rotation = ((Component)weapon).transform.rotation;
				yield return (object)new WaitForFixedUpdate();
			}
		}

		internal static void ApplyLocalControlState(ulong selectedClientId)
		{
			PlayerNetworking localPlayer = ServerManager.GetLocalPlayer();
			HumanAILink val = Object.FindAnyObjectByType<HumanAILink>();
			if ((Object)(object)val != (Object)null)
			{
				CustomGrandpaController customGrandpaController = ((Component)val).GetComponent<CustomGrandpaController>();
				if ((Object)(object)customGrandpaController == (Object)null)
				{
					customGrandpaController = ((Component)val).gameObject.AddComponent<CustomGrandpaController>();
				}
				bool shouldControl = (Object)(object)localPlayer != (Object)null && ((NetworkBehaviour)localPlayer).OwnerClientId == selectedClientId;
				customGrandpaController.SetControlState(localPlayer, shouldControl, selectedClientId != ulong.MaxValue);
			}
		}

		internal static void ForceWakeGrandpaAnimator(HumanAILink grandpaAI)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Invalid comparison between Unknown and I4
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Invalid comparison between Unknown and I4
			if ((Object)(object)grandpaAI == (Object)null || (Object)(object)((GameEntityBase)grandpaAI).NAnimator == (Object)null || (Object)(object)((GameEntityBase)grandpaAI).NAnimator.Animator == (Object)null)
			{
				return;
			}
			Animator animator = ((GameEntityBase)grandpaAI).NAnimator.Animator;
			AnimatorControllerParameter[] parameters = animator.parameters;
			foreach (AnimatorControllerParameter val in parameters)
			{
				if ((int)val.type == 4)
				{
					string text = val.name.ToLowerInvariant();
					if (text.Contains("sleep") || text.Contains("bed") || text.Contains("lying") || text.Contains("lay"))
					{
						animator.SetBool(val.name, false);
					}
				}
				else if ((int)val.type == 9)
				{
					string text2 = val.name.ToLowerInvariant();
					if (text2.Contains("wakeup") || text2.Contains("getup"))
					{
						animator.SetTrigger(val.name);
					}
				}
			}
		}

		internal static void TrySendCaughtEvent(HumanAILink grandpa)
		{
			try
			{
				object obj = typeof(GameEntityAI).GetField("fsm", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(grandpa);
				obj?.GetType().GetMethod("SendEvent", new Type[1] { typeof(string) })?.Invoke(obj, new object[1] { HumanAILink.PlayerCaughtEventName });
			}
			catch
			{
			}
		}
	}
	[BepInPlugin("com.yourname.grandpamod", "Grandpa Control Mod", "2.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public static Plugin Instance;

		private Coroutine vortexRoutine;

		private bool vortexTriggered = false;

		private float nextVortexScan = 0f;

		private void Awake()
		{
			Instance = this;
			try
			{
				Harmony.CreateAndPatchAll(typeof(GrandpaModPatches), (string)null);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Grandpa Mod v2.0.0 loaded! Press 'L' (Host only) to toggle.");
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)$"Failed to patch Harmony: {arg}");
			}
		}

		private void Update()
		{
			if ((Object)(object)NetworkManager.Singleton == (Object)null)
			{
				return;
			}
			if (!GrandpaModPatches.handlersRegistered)
			{
				GrandpaModPatches.RegisterHandlersSafe();
			}
			if (NetworkManager.Singleton.IsServer)
			{
				if (Input.GetKeyDown((KeyCode)108))
				{
					bool flag = GrandpaModPatches.chosenGrandpaClientId == NetworkManager.Singleton.LocalClientId;
					ulong grandpaTarget = (flag ? ulong.MaxValue : NetworkManager.Singleton.LocalClientId);
					SetGrandpaTarget(grandpaTarget);
					((BaseUnityPlugin)this).Logger.LogInfo((object)(flag ? "Grandpa Mode: OFF (Returned to Gnome)" : "Grandpa Mode: ON"));
				}
				if (GrandpaModPatches.chosenGrandpaClientId != ulong.MaxValue && !vortexTriggered && Time.time >= nextVortexScan)
				{
					nextVortexScan = Time.time + 0.3f;
					ScanForActiveVortex();
				}
			}
		}

		public unsafe static void SetGrandpaTarget(ulong targetClientId)
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)NetworkManager.Singleton == (Object)null || !NetworkManager.Singleton.IsServer)
			{
				return;
			}
			FastBufferWriter val = default(FastBufferWriter);
			((FastBufferWriter)(ref val))..ctor(8, (Allocator)2, -1);
			try
			{
				((FastBufferWriter)(ref val)).WriteValueSafe<ulong>(ref targetClientId, default(ForPrimitives));
				NetworkManager.Singleton.CustomMessagingManager.SendNamedMessageToAll("GrandpaChosenMessage", val, (NetworkDelivery)3);
			}
			finally
			{
				((IDisposable)(*(FastBufferWriter*)(&val))/*cast due to .constrained prefix*/).Dispose();
			}
			GrandpaModPatches.chosenGrandpaClientId = targetClientId;
			GrandpaModPatches.ApplyLocalControlState(targetClientId);
			if (targetClientId == ulong.MaxValue && (Object)(object)Instance != (Object)null)
			{
				Instance.vortexTriggered = false;
				if (Instance.vortexRoutine != null)
				{
					((MonoBehaviour)Instance).StopCoroutine(Instance.vortexRoutine);
					Instance.vortexRoutine = null;
				}
			}
		}

		private void ScanForActiveVortex()
		{
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			Transform[] array = Object.FindObjectsByType<Transform>((FindObjectsInactive)0, (FindObjectsSortMode)0);
			Transform[] array2 = array;
			foreach (Transform val in array2)
			{
				string text = ((Object)val).name.ToLowerInvariant();
				if ((text.Contains("vortex") || text.Contains("portal") || text.Contains("blackhole") || text.Contains("exitplayer")) && IsVortexActuallyRunning(((Component)val).gameObject, out var detectedDuration))
				{
					vortexTriggered = true;
					float num = Mathf.Max(0.5f, detectedDuration - 3f);
					Debug.Log((object)$"[GrandpaMod] Воронка НАЧАЛА работать ({((Object)val).name})! Длительность: {detectedDuration:F1}с. Возврат в гнома через {num:F1}с.");
					vortexRoutine = ((MonoBehaviour)this).StartCoroutine(HandleVortexSequence(val.position, num));
					break;
				}
			}
		}

		private bool IsVortexActuallyRunning(GameObject obj, out float detectedDuration)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_017c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			detectedDuration = 9f;
			if ((Object)(object)obj == (Object)null || !obj.activeInHierarchy)
			{
				return false;
			}
			ParticleSystem[] componentsInChildren = obj.GetComponentsInChildren<ParticleSystem>(false);
			ParticleSystem[] array = componentsInChildren;
			foreach (ParticleSystem val in array)
			{
				if ((Object)(object)val != (Object)null && val.isPlaying && val.particleCount > 5)
				{
					MainModule main = val.main;
					if (((MainModule)(ref main)).duration > 3f)
					{
						main = val.main;
						detectedDuration = ((MainModule)(ref main)).duration;
					}
					return true;
				}
			}
			AudioSource[] componentsInChildren2 = obj.GetComponentsInChildren<AudioSource>(false);
			AudioSource[] array2 = componentsInChildren2;
			foreach (AudioSource val2 in array2)
			{
				if ((Object)(object)val2 != (Object)null && val2.isPlaying && val2.time > 0.2f)
				{
					if ((Object)(object)val2.clip != (Object)null && val2.clip.length > 3f)
					{
						detectedDuration = val2.clip.length;
					}
					return true;
				}
			}
			Animator componentInChildren = obj.GetComponentInChildren<Animator>(false);
			if ((Object)(object)componentInChildren != (Object)null && ((Behaviour)componentInChildren).enabled && componentInChildren.speed > 0.01f)
			{
				AnimatorStateInfo currentAnimatorStateInfo = componentInChildren.GetCurrentAnimatorStateInfo(0);
				if (((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime > 0.05f && ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).normalizedTime < 0.95f)
				{
					detectedDuration = ((((AnimatorStateInfo)(ref currentAnimatorStateInfo)).length > 3f) ? ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).length : 9f);
					return true;
				}
			}
			return false;
		}

		private IEnumerator HandleVortexSequence(Vector3 vortexPosition, float delay)
		{
			//IL_000e: 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)
			yield return (object)new WaitForSeconds(delay);
			Debug.Log((object)"[GrandpaMod] Ровно 3 секунды до конца вортекса! Телепортируем гнома и камеру...");
			SetGrandpaTarget(ulong.MaxValue);
			PlayerNetworking localGnome = ServerManager.GetLocalPlayer();
			if ((Object)(object)localGnome != (Object)null)
			{
				Vector3 targetPos = vortexPosition + Vector3.down * 1f;
				((Component)localGnome).transform.position = targetPos;
				Rigidbody rb = ((Component)localGnome).GetComponent<Rigidbody>();
				if ((Object)(object)rb != (Object)null)
				{
					rb