Decompiled source of KvasturBroom v1.0.1

KvasturBroom.dll

Decompiled 5 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using MagicaCloth2;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace VassouraKvastur
{
	internal static class Broom
	{
		internal const string ZdoKey = "vk_riding";

		internal static bool Riding;

		internal static bool Landing;

		internal static float MountT;

		internal const float GrabTime = 0.35f;

		internal const float TakeoffTime = 1f;

		private static readonly FieldRef<Character, Rigidbody> fBody = AccessTools.FieldRefAccess<Character, Rigidbody>("m_body");

		private static readonly FieldRef<Character, Vector3> fMoveDir = AccessTools.FieldRefAccess<Character, Vector3>("m_moveDir");

		private static readonly FieldRef<Character, bool> fRun = AccessTools.FieldRefAccess<Character, bool>("m_run");

		private static readonly FieldRef<Character, Quaternion> fLookYaw = AccessTools.FieldRefAccess<Character, Quaternion>("m_lookYaw");

		private static readonly FieldRef<Character, Vector3> fVel = AccessTools.FieldRefAccess<Character, Vector3>("m_currentVel");

		private static readonly FieldRef<Character, float> fMaxAir = AccessTools.FieldRefAccess<Character, float>("m_maxAirAltitude");

		private static readonly FieldRef<Character, float> fGround = AccessTools.FieldRefAccess<Character, float>("m_lastGroundTouch");

		private static readonly FieldRef<Character, ZSyncAnimation> fAnim = AccessTools.FieldRefAccess<Character, ZSyncAnimation>("m_zanim");

		private static readonly MethodInfo mEye = AccessTools.Method(typeof(Character), "UpdateEyeRotation", (Type[])null, (Type[])null);

		private static readonly MethodInfo mTakeInput = AccessTools.Method(typeof(Character), "TakeInput", (Type[])null, (Type[])null);

		private static readonly MethodInfo mCrouch = AccessTools.Method(typeof(Character), "SetCrouch", (Type[])null, (Type[])null);

		internal const string MountedKey = "kvasturbroom_mounted";

		internal static float Heading;

		internal static float FwdSpeed;

		internal static float VSpeed;

		internal static float YawRate;

		internal static float HorizFactor = 1f;

		internal static void Resume(Player p)
		{
			//IL_004a: 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)
			if (Riding || !Object.op_Implicit((Object)(object)p) || !((Humanoid)p).GetInventory().HaveItem("$item_kvasturbroom", true))
			{
				return;
			}
			Mind.EnsureLoaded(p);
			Mind.OnMount();
			Riding = true;
			Landing = false;
			MountT = 1.35f;
			Heading = ((Component)p).transform.eulerAngles.y;
			FwdSpeed = 0f;
			VSpeed = 0f;
			YawRate = 0f;
			fVel.Invoke((Character)(object)p) = Vector3.zero;
			ZNetView component = ((Component)p).GetComponent<ZNetView>();
			if (component != null)
			{
				ZDO zDO = component.GetZDO();
				if (zDO != null)
				{
					zDO.Set("vk_riding", true);
				}
			}
			fAnim.Invoke((Character)(object)p).SetBool(Plugin.SitAnimation.Value, true);
			((Humanoid)p).HideHandItems(false, true);
			p.m_customData["kvasturbroom_mounted"] = "1";
		}

		internal static void Toggle(Player p)
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			if (Riding)
			{
				if (((Character)p).IsOnGround())
				{
					Stop(p);
				}
				else if (Landing)
				{
					Stop(p);
				}
				else
				{
					Landing = true;
				}
			}
			else
			{
				if (((Character)p).IsAttached() || ((Character)p).IsDead() || ((Character)p).IsSwimming() || ((Character)p).IsTeleporting() || !Mind.CanMount(p))
				{
					return;
				}
				Mind.OnMount();
				p.m_customData["kvasturbroom_mounted"] = "1";
				Riding = true;
				Landing = false;
				MountT = 0f;
				fVel.Invoke((Character)(object)p) = Vector3.zero;
				ZNetView component = ((Component)p).GetComponent<ZNetView>();
				if (component != null)
				{
					ZDO zDO = component.GetZDO();
					if (zDO != null)
					{
						zDO.Set("vk_riding", true);
					}
				}
				fAnim.Invoke((Character)(object)p).SetTrigger("interact");
				((Humanoid)p).HideHandItems(false, true);
			}
		}

		internal static void Stop(Player p)
		{
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			Riding = false;
			Landing = false;
			if (!Object.op_Implicit((Object)(object)p))
			{
				return;
			}
			p.m_customData["kvasturbroom_mounted"] = "0";
			Mind.Save(p);
			fBody.Invoke((Character)(object)p).useGravity = true;
			fMaxAir.Invoke((Character)(object)p) = ((Component)p).transform.position.y;
			ZNetView component = ((Component)p).GetComponent<ZNetView>();
			if (component != null)
			{
				ZDO zDO = component.GetZDO();
				if (zDO != null)
				{
					zDO.Set("vk_riding", false);
				}
			}
			fAnim.Invoke((Character)(object)p).SetBool(Plugin.SitAnimation.Value, false);
		}

		internal static void Fly(Player p, float dt)
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: 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_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: 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_0155: 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_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: 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_01c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ce: Invalid comparison between Unknown and I4
			//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_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0295: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_066d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0672: Unknown result type (might be due to invalid IL or missing references)
			//IL_0674: Unknown result type (might be due to invalid IL or missing references)
			//IL_0676: Unknown result type (might be due to invalid IL or missing references)
			//IL_067b: Unknown result type (might be due to invalid IL or missing references)
			//IL_068b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0690: Unknown result type (might be due to invalid IL or missing references)
			//IL_069d: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_06b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_06c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_06cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_06d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_06ed: Unknown result type (might be due to invalid IL or missing references)
			if (((Character)p).IsDead() || ((Character)p).IsAttached() || ((Character)p).IsTeleporting() || !((Humanoid)p).GetInventory().HaveItem("$item_kvasturbroom", true))
			{
				if (((Character)p).IsOnGround() || ((Character)p).IsDead())
				{
					Stop(p);
					return;
				}
				Landing = true;
			}
			bool flag = (bool)mTakeInput.Invoke(p, null);
			if (MountT == 0f)
			{
				Heading = ((Component)p).transform.eulerAngles.y;
				FwdSpeed = 0f;
				VSpeed = 0f;
				YawRate = 0f;
			}
			MountT += dt;
			bool flag2 = MountT < 0.35f && !Landing;
			bool flag3 = !flag2 && MountT < 1.35f && !Landing;
			float num = 0f;
			float num2 = 0f;
			float num3 = Heading;
			Transform val = (Object.op_Implicit((Object)(object)GameCamera.instance) ? ((Component)GameCamera.instance).transform : null);
			if (Object.op_Implicit((Object)(object)val) && flag)
			{
				Vector3 val2 = Vector3.ProjectOnPlane(val.forward, Vector3.up);
				Vector3 normalized = ((Vector3)(ref val2)).normalized;
				Vector3 val3 = Vector3.Cross(Vector3.up, normalized);
				Vector3 val4 = fMoveDir.Invoke((Character)(object)p);
				num = Vector3.Dot(val4, normalized);
				num2 = Vector3.Dot(val4, val3);
				Quaternion val5 = Quaternion.LookRotation(normalized);
				num3 = ((Quaternion)(ref val5)).eulerAngles.y;
			}
			bool num4 = fRun.Invoke((Character)(object)p);
			float pitchCmd = 0f;
			if (flag && !flag2 && !Landing)
			{
				KeyboardShortcut value = Plugin.UpKey.Value;
				if (!ZInput.GetKey(((KeyboardShortcut)(ref value)).MainKey, true))
				{
					value = Plugin.UpKey.Value;
					if (((int)((KeyboardShortcut)(ref value)).MainKey != 32 || !ZInput.GetButton("Jump")) && !ZInput.GetButton("JoyJump"))
					{
						value = Plugin.DownKey.Value;
						if (ZInput.GetKey(((KeyboardShortcut)(ref value)).MainKey, true) || ZInput.GetButton("JoyCrouch"))
						{
							pitchCmd = -1f;
						}
						goto IL_021f;
					}
				}
				pitchCmd = 1f;
				goto IL_021f;
			}
			goto IL_02f8;
			IL_02f8:
			if (flag2)
			{
				num = 0f;
				num2 = 0f;
			}
			float num5 = (num4 ? Plugin.RunSpeed.Value : Plugin.Speed.Value);
			float sTarget = ((num > 0.1f) ? (num5 * num) : ((num < -0.1f) ? (Plugin.Speed.Value * 0.35f * num) : 0f));
			if (Landing)
			{
				sTarget = Mathf.Min(sTarget, Plugin.Speed.Value * 0.5f);
			}
			if (flag3)
			{
				sTarget *= (MountT - 0.35f) / 1f;
			}
			Mind.Steer(p, ref sTarget, ref pitchCmd, flag2 || flag3 || Landing);
			float num6 = ((Mathf.Abs(sTarget) > Mathf.Abs(FwdSpeed)) ? Plugin.Accel.Value : Plugin.Drag.Value);
			FwdSpeed = Mathf.MoveTowards(FwdSpeed, sTarget, num6 * dt);
			float num7 = Mathf.Clamp01(Mathf.Abs(FwdSpeed) / Plugin.RunSpeed.Value);
			float num8 = Mathf.Lerp(Plugin.TurnRateSlow.Value, Plugin.TurnRateFast.Value, num7);
			float wantRate = num2 * num8;
			if (Plugin.FollowCamera.Value && Mathf.Abs(num2) < 0.1f)
			{
				wantRate = Mathf.Clamp(Mathf.DeltaAngle(Heading, num3) * 2.5f, 0f - num8, num8);
			}
			wantRate = Mind.TurnBias(wantRate, num8, Heading, ((Component)p).transform.position);
			if (Mind.Warning)
			{
				wantRate += Mathf.Sin(Time.time * 9f) * num8 * 0.8f;
			}
			YawRate = Mathf.MoveTowards(YawRate, wantRate, num8 * 3f * dt);
			Heading += YawRate * dt;
			float num9 = Mathf.Abs(FwdSpeed);
			float num10 = Plugin.ClimbAngle.Value * ((float)Math.PI / 180f);
			float num11 = Mathf.Clamp01((num9 - 1f) / 6f) * Mathf.Abs(pitchCmd);
			float num12 = Mathf.Lerp(pitchCmd * Plugin.VertSpeed.Value, pitchCmd * num9 * Mathf.Sin(num10), num11);
			float num13 = Mathf.Lerp(1f, Mathf.Cos(num10), num11);
			if (Mind.Diving)
			{
				num12 = 0f - Plugin.DiveSpeed.Value;
				num13 = 1f;
			}
			if (flag2)
			{
				VSpeed = (((Character)p).IsOnGround() ? 0f : (-1f));
			}
			else if (flag3)
			{
				VSpeed = 3f * Mathf.Sin((MountT - 0.35f) / 1f * (float)Math.PI);
			}
			else if (Landing)
			{
				VSpeed = Mathf.MoveTowards(VSpeed, 0f - Plugin.LandSpeed.Value, 8f * dt);
				if (((Character)p).IsOnGround())
				{
					Stop(p);
					return;
				}
			}
			else
			{
				VSpeed = Mathf.MoveTowards(VSpeed, num12, Plugin.VertAccel.Value * dt);
			}
			HorizFactor = Mathf.MoveTowards(HorizFactor, num13, 2f * dt);
			float num14 = ((!flag2 && !flag3 && !Landing && Mathf.Abs(pitchCmd) < 0.05f) ? (Mathf.Sin(Time.time * 1.7f) * 0.25f * (1f - num7)) : 0f);
			Rigidbody obj = fBody.Invoke((Character)(object)p);
			Quaternion val6 = Quaternion.Euler(0f, Heading, 0f);
			Vector3 val7 = val6 * Vector3.forward * (FwdSpeed * HorizFactor) + Vector3.up * (VSpeed + num14);
			fVel.Invoke((Character)(object)p) = val7;
			obj.useGravity = false;
			obj.linearVelocity = val7;
			obj.angularVelocity = Vector3.zero;
			obj.rotation = val6;
			fMaxAir.Invoke((Character)(object)p) = ((Component)p).transform.position.y;
			fGround.Invoke((Character)(object)p) = 0f;
			mCrouch.Invoke(p, new object[1] { false });
			ZSyncAnimation val8 = fAnim.Invoke((Character)(object)p);
			val8.SetBool("falling", false);
			if (!flag2)
			{
				val8.SetBool(Plugin.SitAnimation.Value, true);
			}
			mEye.Invoke(p, null);
			Mind.Tick(p, dt, FwdSpeed, VSpeed, num, pitchCmd, flag2 || flag3 || Landing);
			return;
			IL_021f:
			if (pitchCmd == 0f && Plugin.TriggersClimb.Value)
			{
				float joyRTrigger = ZInput.GetJoyRTrigger();
				float joyLTrigger = ZInput.GetJoyLTrigger();
				if (joyRTrigger > 0.15f || joyLTrigger > 0.15f)
				{
					pitchCmd = Mathf.Clamp(joyRTrigger - joyLTrigger, -1f, 1f);
				}
			}
			if (pitchCmd == 0f && Plugin.CameraClimb.Value && Object.op_Implicit((Object)(object)val) && num > 0.1f)
			{
				float num15 = (0f - Mathf.Asin(Mathf.Clamp(val.forward.y, -1f, 1f))) * 57.29578f;
				float value2 = Plugin.CameraDeadZone.Value;
				if (Mathf.Abs(num15) > value2)
				{
					pitchCmd = Mathf.Clamp((0f - (num15 - Mathf.Sign(num15) * value2)) / 25f, -1f, 1f);
				}
			}
			goto IL_02f8;
		}
	}
	[HarmonyPatch(typeof(Character), "UpdateMotion")]
	internal static class UpdateMotionPatch
	{
		private static bool Prefix(Character __instance, float dt)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			if (!Broom.Riding || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			Broom.Fly((Player)__instance, dt);
			return false;
		}
	}
	[HarmonyPatch(typeof(Character), "Jump")]
	internal static class JumpPatch
	{
		private static bool Prefix(Character __instance)
		{
			if (Broom.Riding)
			{
				return !((Object)(object)__instance == (Object)(object)Player.m_localPlayer);
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Humanoid), "UseItem")]
	internal static class UseItemPatch
	{
		private static bool Prefix(Humanoid __instance, ItemData item)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			if (item == null || item.m_shared.m_name != "$item_kvasturbroom" || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return true;
			}
			Broom.Toggle((Player)__instance);
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "OnDestroy")]
	internal static class PlayerDestroyPatch
	{
		private static void Prefix(Player __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				Broom.Riding = false;
				Broom.Landing = false;
			}
		}
	}
	[HarmonyPatch(typeof(Player), "Awake")]
	internal static class PlayerAwakePatch
	{
		private static void Postfix(Player __instance)
		{
			((Component)__instance).gameObject.AddComponent<BroomVisual>();
		}
	}
	internal sealed class BroomVisual : MonoBehaviour
	{
		private static readonly List<BroomVisual> all = new List<BroomVisual>();

		internal const string SweepKey = "vk_sweep";

		private ZNetView nview;

		private GameObject broom;

		private float next;

		private bool riding;

		private float since = 99f;

		private float sweepUntil;

		private Transform visual;

		private Vector3 lastPos;

		private Vector3 estVel;

		private float lastYaw;

		private float bank;

		private float pitch;

		private float acc;

		private float estYaw;

		private Animator anim;

		private Transform spine;

		private Transform armL;

		private Transform foreL;

		private Transform handL;

		private Transform armR;

		private Transform foreR;

		private Transform handR;

		private Transform thighL;

		private Transform shinL;

		private Transform footL;

		private Transform thighR;

		private Transform shinR;

		private Transform footR;

		private bool bonesOk;

		private Transform[][] fingersL;

		private Transform[][] fingersR;

		private Transform attachR;

		private Transform attachL;

		private static Vector3 shaftAxis;

		private static readonly FieldRef<Character, GameObject> fVisual = AccessTools.FieldRefAccess<Character, GameObject>("m_visual");

		private MagicaWindZone capeZone;

		private Vector3 capeVel;

		private static readonly string[] fingerNames = new string[5] { "Index", "Middle", "Ring", "Little", "Thumb" };

		private readonly List<Transform> touched = new List<Transform>();

		private Quaternion[] baseRot;

		private Quaternion[] wroteRot;

		private bool wrote;

		private readonly Dictionary<Transform, float> wantSign = new Dictionary<Transform, float>();

		private Transform BodyFrame
		{
			get
			{
				if (!Object.op_Implicit((Object)(object)visual))
				{
					return ((Component)this).transform;
				}
				return visual;
			}
		}

		private static Vector3 ShaftAxis()
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d8: 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_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: 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_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: 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_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: 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_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			if (shaftAxis != Vector3.zero || !Object.op_Implicit((Object)(object)ObjectDB.instance))
			{
				return shaftAxis;
			}
			string[] array = new string[5] { "SpearFlint", "SpearBronze", "SpearElderbark", "Torch", "Club" };
			foreach (string text in array)
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text);
				Transform val = (Object.op_Implicit((Object)(object)itemPrefab) ? itemPrefab.transform.Find("attach") : null);
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				Bounds val2 = default(Bounds);
				bool flag = false;
				MeshFilter[] componentsInChildren = ((Component)val).GetComponentsInChildren<MeshFilter>(true);
				foreach (MeshFilter val3 in componentsInChildren)
				{
					if (!Object.op_Implicit((Object)(object)val3.sharedMesh))
					{
						continue;
					}
					Bounds bounds = val3.sharedMesh.bounds;
					for (int k = 0; k < 8; k++)
					{
						Vector3 val4 = ((Bounds)(ref bounds)).center + Vector3.Scale(((Bounds)(ref bounds)).extents, new Vector3((float)(((k & 1) != 0) ? 1 : (-1)), (float)(((k & 2) != 0) ? 1 : (-1)), (float)(((k & 4) != 0) ? 1 : (-1))));
						Vector3 val5 = val.InverseTransformPoint(((Component)val3).transform.TransformPoint(val4));
						if (!flag)
						{
							((Bounds)(ref val2))..ctor(val5, Vector3.zero);
							flag = true;
						}
						else
						{
							((Bounds)(ref val2)).Encapsulate(val5);
						}
					}
				}
				if (flag)
				{
					Vector3 size = ((Bounds)(ref val2)).size;
					shaftAxis = ((size.x >= size.y && size.x >= size.z) ? Vector3.right : ((size.y >= size.z) ? Vector3.up : Vector3.forward));
					return shaftAxis;
				}
			}
			shaftAxis = Vector3.up;
			return shaftAxis;
		}

		private void Awake()
		{
			nview = ((Component)this).GetComponent<ZNetView>();
			all.Add(this);
		}

		private void FindBones()
		{
			bonesOk = true;
			anim = ((Component)this).GetComponentInChildren<Animator>();
			spine = B((HumanBodyBones)7, "Spine1");
			thighL = B((HumanBodyBones)1, "LeftUpLeg");
			shinL = B((HumanBodyBones)3, "LeftLeg");
			footL = B((HumanBodyBones)5, "LeftFoot");
			thighR = B((HumanBodyBones)2, "RightUpLeg");
			shinR = B((HumanBodyBones)4, "RightLeg");
			footR = B((HumanBodyBones)6, "RightFoot");
			armL = B((HumanBodyBones)13, "LeftArm");
			foreL = B((HumanBodyBones)15, "LeftForeArm");
			handL = B((HumanBodyBones)17, "LeftHand");
			armR = B((HumanBodyBones)14, "RightArm");
			foreR = B((HumanBodyBones)16, "RightForeArm");
			handR = B((HumanBodyBones)18, "RightHand");
			fingersL = Fingers("Left", left: true);
			fingersR = Fingers("Right", left: false);
			VisEquipment component = ((Component)this).GetComponent<VisEquipment>();
			if (Object.op_Implicit((Object)(object)component))
			{
				attachR = component.m_rightHand;
				attachL = component.m_leftHand;
			}
			if (!Object.op_Implicit((Object)(object)armL) || !Object.op_Implicit((Object)(object)foreL) || !Object.op_Implicit((Object)(object)handL) || !Object.op_Implicit((Object)(object)armR) || !Object.op_Implicit((Object)(object)foreR) || !Object.op_Implicit((Object)(object)handR))
			{
				Debug.LogWarning((object)"[KvasturBroom] Arm bones not found; the hands won't hold the shaft.");
				armL = null;
			}
			Transform B(HumanBodyBones hb, string name)
			{
				//IL_0022: Unknown result type (might be due to invalid IL or missing references)
				Transform val = null;
				if (Object.op_Implicit((Object)(object)anim) && anim.isHuman)
				{
					val = anim.GetBoneTransform(hb);
				}
				if (!Object.op_Implicit((Object)(object)val))
				{
					Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
					foreach (Transform val2 in componentsInChildren)
					{
						if (((Object)val2).name == name)
						{
							val = val2;
							break;
						}
					}
				}
				return val;
			}
		}

		private void Tilt()
		{
			//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0137: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: 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_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01be: 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_0080: 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_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: Unknown result type (might be due to invalid IL or missing references)
			//IL_0331: Unknown result type (might be due to invalid IL or missing references)
			//IL_0333: Unknown result type (might be due to invalid IL or missing references)
			//IL_0335: Unknown result type (might be due to invalid IL or missing references)
			//IL_0337: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)visual))
			{
				Character component = ((Component)this).GetComponent<Character>();
				GameObject val = (Object.op_Implicit((Object)(object)component) ? fVisual.Invoke(component) : null);
				visual = (Object.op_Implicit((Object)(object)val) ? val.transform : null);
				if (!Object.op_Implicit((Object)(object)visual) || (Object)(object)visual == (Object)(object)((Component)this).transform)
				{
					visual = null;
					return;
				}
				lastPos = ((Component)this).transform.position;
				lastYaw = ((Component)this).transform.eulerAngles.y;
			}
			float deltaTime = Time.deltaTime;
			if (deltaTime <= 0f)
			{
				return;
			}
			float yawRate;
			float num;
			float num2;
			if ((Object)(object)nview != (Object)null && nview.IsOwner() && Broom.Riding)
			{
				yawRate = Broom.YawRate;
				num = Broom.FwdSpeed;
				num2 = Broom.VSpeed;
			}
			else
			{
				acc += deltaTime;
				Vector3 val2 = ((Component)this).transform.position - lastPos;
				if (((Vector3)(ref val2)).sqrMagnitude > 1E-06f || acc > 0.3f)
				{
					estVel = (((Component)this).transform.position - lastPos) / acc;
					estYaw = Mathf.DeltaAngle(lastYaw, ((Component)this).transform.eulerAngles.y) / acc;
					lastPos = ((Component)this).transform.position;
					lastYaw = ((Component)this).transform.eulerAngles.y;
					acc = 0f;
				}
				yawRate = estYaw;
				num = Vector3.Dot(estVel, ((Component)this).transform.forward);
				num2 = estVel.y;
			}
			Vector3 val3 = default(Vector3);
			((Vector3)(ref val3))..ctor(0f, num2, 0f);
			float num3 = (riding ? Mathf.Clamp((0f - yawRate) * Mathf.Abs(num) * Plugin.BankFactor.Value, 0f - Plugin.MaxBank.Value, Plugin.MaxBank.Value) : 0f);
			float num4 = (riding ? Mathf.Clamp((0f - Mathf.Atan2(val3.y, Mathf.Max(3f, Mathf.Abs(num)))) * 57.29578f * 0.8f, 0f - Plugin.MaxPitch.Value, Plugin.MaxPitch.Value) : 0f);
			float num5 = 1f - Mathf.Exp(-6f * deltaTime);
			bank = Mathf.Lerp(bank, num3, num5);
			pitch = Mathf.Lerp(pitch, num4, num5);
			if (!riding && Mathf.Abs(bank) < 0.05f && Mathf.Abs(pitch) < 0.05f)
			{
				bank = 0f;
				pitch = 0f;
			}
			Quaternion val4 = Quaternion.Euler(pitch, 0f, bank);
			Vector3 value = Plugin.BroomOffset.Value;
			visual.localRotation = val4;
			visual.localPosition = value - val4 * value;
			if (Object.op_Implicit((Object)(object)broom) && (Object)(object)broom.transform.parent != (Object)(object)visual)
			{
				broom.transform.SetParent(visual, false);
			}
		}

		private void Cape()
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0181: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: 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_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Unknown result type (might be due to invalid IL or missing references)
			if (!riding || !(Plugin.CapeWind.Value > 0f))
			{
				if (Object.op_Implicit((Object)(object)capeZone) && ((Component)capeZone).gameObject.activeSelf)
				{
					((Component)capeZone).gameObject.SetActive(false);
				}
				capeVel = Vector3.zero;
				return;
			}
			if (!Object.op_Implicit((Object)(object)capeZone))
			{
				GameObject val = new GameObject("KvasturCapeWind");
				val.transform.SetParent(((Component)this).transform, false);
				val.transform.localPosition = new Vector3(0f, 1.3f, 0f);
				capeZone = val.AddComponent<MagicaWindZone>();
				capeZone.mode = (Mode)2;
				capeZone.size = new Vector3(2.5f, 3f, 2.5f);
				capeZone.isAddition = true;
				capeZone.main = 0f;
			}
			if (!((Component)capeZone).gameObject.activeSelf)
			{
				((Component)capeZone).gameObject.SetActive(true);
			}
			Vector3 val2 = (((Object)(object)nview != (Object)null && nview.IsOwner() && Broom.Riding) ? (Quaternion.Euler(0f, Broom.Heading, 0f) * Vector3.forward * (Broom.FwdSpeed * Broom.HorizFactor) + Vector3.up * Broom.VSpeed) : estVel);
			capeVel = Vector3.Lerp(capeVel, val2, 1f - Mathf.Exp(-3f * Time.deltaTime));
			float magnitude = ((Vector3)(ref capeVel)).magnitude;
			capeZone.main = magnitude * Plugin.CapeWind.Value;
			capeZone.turbulence = Mathf.Clamp01(Plugin.CapeFlutter.Value);
			if (magnitude > 0.2f)
			{
				capeZone.SetWindDirection(-capeVel / magnitude, false);
			}
		}

		private Transform[][] Fingers(string side, bool left)
		{
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			Transform[][] array = new Transform[5][];
			for (int i = 0; i < 5; i++)
			{
				array[i] = (Transform[])(object)new Transform[3];
				for (int j = 0; j < 3; j++)
				{
					Transform val = null;
					if (Object.op_Implicit((Object)(object)anim) && anim.isHuman && Enum.TryParse<HumanBodyBones>((left ? "Left" : "Right") + fingerNames[i] + j switch
					{
						1 => "Intermediate", 
						0 => "Proximal", 
						_ => "Distal", 
					}, out HumanBodyBones result))
					{
						val = anim.GetBoneTransform(result);
					}
					if (!Object.op_Implicit((Object)(object)val))
					{
						string text = side + "Hand" + ((fingerNames[i] == "Little") ? "Pinky" : fingerNames[i]) + (j + 1);
						Transform[] componentsInChildren = ((Component)this).GetComponentsInChildren<Transform>(true);
						foreach (Transform val2 in componentsInChildren)
						{
							if (((Object)val2).name == text)
							{
								val = val2;
								break;
							}
						}
					}
					array[i][j] = val;
				}
				if ((Object)(object)array[i][0] == (Object)null)
				{
					array[i] = null;
				}
			}
			return array;
		}

		private void CollectTouched()
		{
			touched.Clear();
			Transform[] array = (Transform[])(object)new Transform[13]
			{
				spine, armL, foreL, handL, armR, foreR, handR, thighL, shinL, footL,
				thighR, shinR, footR
			};
			foreach (Transform val in array)
			{
				if (Object.op_Implicit((Object)(object)val))
				{
					touched.Add(val);
				}
			}
			Transform[][][] array2 = new Transform[2][][] { fingersL, fingersR };
			foreach (Transform[][] array3 in array2)
			{
				if (array3 == null)
				{
					continue;
				}
				Transform[][] array4 = array3;
				foreach (Transform[] array5 in array4)
				{
					if (array5 == null)
					{
						continue;
					}
					array = array5;
					foreach (Transform val2 in array)
					{
						if (Object.op_Implicit((Object)(object)val2))
						{
							touched.Add(val2);
						}
					}
				}
			}
			baseRot = (Quaternion[])(object)new Quaternion[touched.Count];
			wroteRot = (Quaternion[])(object)new Quaternion[touched.Count];
			wrote = false;
		}

		private bool RestoreBase()
		{
			//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_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			bool result = !wrote;
			for (int i = 0; i < touched.Count; i++)
			{
				Transform val = touched[i];
				if (Object.op_Implicit((Object)(object)val))
				{
					if (!wrote || val.localRotation != wroteRot[i])
					{
						baseRot[i] = val.localRotation;
						result = true;
					}
					else
					{
						val.localRotation = baseRot[i];
					}
				}
			}
			return result;
		}

		private void RecordWritten()
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < touched.Count; i++)
			{
				if (Object.op_Implicit((Object)(object)touched[i]))
				{
					wroteRot[i] = touched[i].localRotation;
				}
			}
			wrote = true;
		}

		private void UpdatePose()
		{
			//IL_014e: 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)
			//IL_0159: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			Tilt();
			Cape();
			if (!bonesOk)
			{
				FindBones();
				CollectTouched();
			}
			if (!riding || !Object.op_Implicit((Object)(object)broom) || !broom.activeSelf)
			{
				if (wrote)
				{
					RestoreBase();
					wrote = false;
				}
			}
			else if (Object.op_Implicit((Object)(object)armL))
			{
				RestoreBase();
				float num = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01(since / 0.35f));
				Legs(num);
				if (Object.op_Implicit((Object)(object)spine))
				{
					spine.rotation = Quaternion.AngleAxis(Plugin.Lean.Value * num, BodyFrame.right) * Quaternion.AngleAxis((0f - Plugin.LeanSide.Value) * num, BodyFrame.forward) * Quaternion.AngleAxis(Plugin.LeanTwist.Value * num, BodyFrame.up) * spine.rotation;
				}
				Transform transform = broom.transform;
				Hold(armR, foreR, handR, attachR, fingersR, transform.TransformPoint(Plugin.RightHand.Value), transform.forward, num, 1f);
				Hold(armL, foreL, handL, attachL, fingersL, transform.TransformPoint(Plugin.LeftHand.Value), transform.forward, num, -1f);
				RecordWritten();
			}
		}

		private void Hold(Transform up, Transform lo, Transform hand, Transform attach, Transform[][] fingers, Vector3 center, Vector3 axis, float w, float side)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: 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_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0163: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: Unknown result type (might be due to invalid IL or missing references)
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			axis = ((Vector3)(ref axis)).normalized;
			Vector3 val = BodyFrame.right * side;
			if (!Object.op_Implicit((Object)(object)attach))
			{
				return;
			}
			Vector3 val2 = attach.rotation * ShaftAxis();
			if (!wantSign.TryGetValue(hand, out var value))
			{
				value = ((Vector3.Dot(val2, axis) >= 0f) ? 1f : (-1f));
				if (w >= 0.99f)
				{
					wantSign[hand] = value;
				}
			}
			Vector3 val3 = axis * value;
			Quaternion val4 = Quaternion.FromToRotation(val2, val3);
			Vector3 val5 = Vector3.ProjectOnPlane(val4 * (hand.position - attach.position), axis);
			Vector3 val6 = Vector3.ProjectOnPlane(val * 0.75f + BodyFrame.up * 0.35f, axis);
			Quaternion val7 = Quaternion.identity;
			if (((Vector3)(ref val5)).sqrMagnitude > 1E-08f && ((Vector3)(ref val6)).sqrMagnitude > 1E-08f)
			{
				val7 = ((Vector3.Dot(((Vector3)(ref val5)).normalized, ((Vector3)(ref val6)).normalized) < -0.999f) ? Quaternion.AngleAxis(180f, axis) : Quaternion.FromToRotation(val5, val6));
			}
			val7 = Quaternion.AngleAxis((side > 0f) ? Plugin.RollRight.Value : Plugin.RollLeft.Value, axis) * val7;
			val4 = val7 * val4;
			Quaternion val8 = val4 * hand.rotation;
			Vector3 val9 = val4 * (attach.position - hand.position);
			Grip(up, lo, hand, center - val9, w, side);
			hand.rotation = Quaternion.Slerp(hand.rotation, val8, w);
			ExtraHandRot(hand, side, w);
			CurlFingers(hand, attach, fingers, w);
		}

		private void CurlFingers(Transform hand, Transform attach, Transform[][] fingers, float w)
		{
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e2: 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)
			//IL_00e9: 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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			if (fingers == null || !Object.op_Implicit((Object)(object)attach))
			{
				return;
			}
			for (int i = 0; i < 5; i++)
			{
				Transform[] array = fingers[i];
				if (array == null)
				{
					continue;
				}
				float num = ((i == 4) ? Plugin.ThumbCurl.Value : Plugin.FingerCurl.Value) * w;
				if (num <= 0f)
				{
					continue;
				}
				for (int j = 0; j < 3; j++)
				{
					Transform val = array[j];
					if (!Object.op_Implicit((Object)(object)val))
					{
						break;
					}
					Transform val2 = ((j < 2) ? array[j + 1] : ((val.childCount > 0) ? val.GetChild(0) : null));
					Vector3 val3 = (Object.op_Implicit((Object)(object)val2) ? (val2.position - val.position) : (val.position - ((j > 0) ? array[j - 1].position : hand.position)));
					if (!(((Vector3)(ref val3)).sqrMagnitude < 1E-08f))
					{
						Vector3 val4 = Vector3.ProjectOnPlane(attach.position - val.position, val3);
						if (!(((Vector3)(ref val4)).sqrMagnitude < 1E-08f))
						{
							Vector3 val5 = Vector3.Cross(val3, val4);
							Vector3 normalized = ((Vector3)(ref val5)).normalized;
							val.rotation = Quaternion.AngleAxis(num * ((j == 2) ? 0.8f : 1f), normalized) * val.rotation;
						}
					}
				}
			}
		}

		private void Legs(float w)
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: 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_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: 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_01c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0219: Unknown result type (might be due to invalid IL or missing references)
			//IL_021d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_022a: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Unknown result type (might be due to invalid IL or missing references)
			//IL_023b: Unknown result type (might be due to invalid IL or missing references)
			Transform bodyFrame = BodyFrame;
			float num = Plugin.LegHip.Value * w;
			float num2 = Plugin.LegSpread.Value * w;
			float num3 = Plugin.LegKnee.Value * w;
			float num4 = Plugin.LegFoot.Value * w;
			float num5 = Plugin.LegKneesIn.Value * w;
			if (num == 0f && num2 == 0f && num3 == 0f && num4 == 0f && num5 == 0f)
			{
				return;
			}
			for (int i = 0; i < 2; i++)
			{
				float num6 = ((i == 0) ? (-1f) : 1f);
				Transform val = ((i == 0) ? thighL : thighR);
				Transform val2 = ((i == 0) ? shinL : shinR);
				Transform val3 = ((i == 0) ? footL : footR);
				if (Object.op_Implicit((Object)(object)val))
				{
					val.rotation = Quaternion.AngleAxis(num2 * num6, bodyFrame.forward) * Quaternion.AngleAxis(0f - num, bodyFrame.right) * val.rotation;
				}
				if (Object.op_Implicit((Object)(object)val2))
				{
					val2.rotation = Quaternion.AngleAxis(num3, bodyFrame.right) * val2.rotation;
				}
				if (Object.op_Implicit((Object)(object)val3))
				{
					val3.rotation = Quaternion.AngleAxis(0f - num4, bodyFrame.right) * val3.rotation;
				}
				if (num5 != 0f && Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2) && Object.op_Implicit((Object)(object)val3))
				{
					Vector3 val4 = val3.position - val.position;
					if (((Vector3)(ref val4)).sqrMagnitude > 1E-06f)
					{
						((Vector3)(ref val4)).Normalize();
						Vector3 val5 = val2.position - val.position;
						float num7 = Vector3.Dot(val5, bodyFrame.right) * num6;
						Quaternion val6 = Quaternion.AngleAxis(((Vector3.Dot(Quaternion.AngleAxis(5f, val4) * val5, bodyFrame.right) * num6 < num7) ? 1f : (-1f)) * num5, val4);
						Quaternion rotation = val3.rotation;
						val.rotation = val6 * val.rotation;
						val3.rotation = rotation;
					}
				}
			}
		}

		private void ExtraHandRot(Transform hand, float side, float w)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: 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_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			Vector3 val = ((side > 0f) ? Plugin.HandRotRight.Value : Plugin.HandRotLeft.Value);
			if (!(val == Vector3.zero))
			{
				Transform bodyFrame = BodyFrame;
				hand.rotation = Quaternion.AngleAxis(val.x * w, bodyFrame.right) * Quaternion.AngleAxis(val.y * w * side, bodyFrame.up) * Quaternion.AngleAxis(val.z * w * side, bodyFrame.forward) * hand.rotation;
			}
		}

		private void Grip(Transform up, Transform lo, Transform hand, Vector3 target, float w, float side)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0039: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0094: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			//IL_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: 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_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016e: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0170: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: 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_0188: 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_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_019a: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: 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_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: 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_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: 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_01c8: Unknown result type (might be due to invalid IL or missing references)
			Vector3 position = up.position;
			Vector3 position2 = lo.position;
			Vector3 position3 = hand.position;
			target = Vector3.Lerp(position3, target, w);
			Vector3 val = position2 - position;
			float magnitude = ((Vector3)(ref val)).magnitude;
			val = position3 - position2;
			float magnitude2 = ((Vector3)(ref val)).magnitude;
			Vector3 val2 = target - position;
			float num = Mathf.Clamp(((Vector3)(ref val2)).magnitude, 0.05f, (magnitude + magnitude2) * 0.999f);
			Vector3 normalized = ((Vector3)(ref val2)).normalized;
			Vector3 val3 = -BodyFrame.up * 0.6f + BodyFrame.right * side * 0.5f - BodyFrame.forward * 0.1f;
			val3 = Quaternion.AngleAxis(((side > 0f) ? Plugin.ElbowRight.Value : Plugin.ElbowLeft.Value) * side, normalized) * val3;
			val = Vector3.ProjectOnPlane(val3, normalized);
			Vector3 normalized2 = ((Vector3)(ref val)).normalized;
			float num2 = Mathf.Clamp((magnitude * magnitude + num * num - magnitude2 * magnitude2) / (2f * magnitude * num), -1f, 1f);
			Vector3 val4 = position + normalized * (magnitude * num2) + normalized2 * (magnitude * Mathf.Sqrt(1f - num2 * num2));
			up.rotation = Quaternion.FromToRotation(position2 - position, val4 - position) * up.rotation;
			position2 = lo.position;
			position3 = hand.position;
			lo.rotation = Quaternion.FromToRotation(position3 - position2, position + normalized * num - position2) * lo.rotation;
		}

		private void OnDestroy()
		{
			all.Remove(this);
		}

		internal static void RebuildAll()
		{
			foreach (BroomVisual item in all)
			{
				if (Object.op_Implicit((Object)(object)item.broom))
				{
					Object.Destroy((Object)(object)item.broom);
					item.broom = null;
				}
			}
		}

		private void Update()
		{
			UpdateBroom();
			UpdatePose();
		}

		private void UpdateBroom()
		{
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: 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_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0225: Unknown result type (might be due to invalid IL or missing references)
			//IL_025b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0371: Unknown result type (might be due to invalid IL or missing references)
			//IL_0372: Unknown result type (might be due to invalid IL or missing references)
			//IL_0375: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_03c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: 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_02e5: 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_03f8: Unknown result type (might be due to invalid IL or missing references)
			if (Broom.Riding && (Object)(object)nview != (Object)null && nview.IsOwner())
			{
				KeyboardShortcut value = Plugin.DismountKey.Value;
				if (ZInput.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey, true))
				{
					Player localPlayer = Player.m_localPlayer;
					if (Object.op_Implicit((Object)(object)localPlayer) && (Object)(object)((Component)localPlayer).gameObject == (Object)(object)((Component)this).gameObject && !Console.IsVisible() && (!Object.op_Implicit((Object)(object)Chat.instance) || !Chat.instance.HasFocus()) && !Menu.IsVisible() && !InventoryGui.IsVisible() && (Object)(object)((Humanoid)localPlayer).GetHoverObject() == (Object)null)
					{
						Broom.Toggle(localPlayer);
					}
				}
			}
			if (Time.time >= next)
			{
				next = Time.time + 0.1f;
				ZDO val = (Object.op_Implicit((Object)(object)nview) ? nview.GetZDO() : null);
				bool flag = val != null && val.GetBool("vk_riding", false);
				if (flag != riding)
				{
					riding = flag;
					since = 0f;
					wantSign.Clear();
				}
				sweepUntil = ((val != null) ? val.GetFloat("vk_sweep", 0f) : 0f);
				bool flag2 = !riding && Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.GetTimeSeconds() < (double)sweepUntil;
				if ((riding || flag2) && !Object.op_Implicit((Object)(object)broom))
				{
					broom = Build(((Component)this).transform);
				}
			}
			since += Time.deltaTime;
			if (Object.op_Implicit((Object)(object)broom))
			{
				Vector3 value2 = Plugin.BroomOffset.Value;
				Vector3 val2 = value2 + new Vector3(0f, 0.35f, 0.75f);
				if (riding)
				{
					broom.SetActive(true);
					float num = Mathf.SmoothStep(0f, 1f, Mathf.Clamp01(since / 0.35f));
					broom.transform.localPosition = Vector3.Lerp(val2, value2, num);
					broom.transform.localRotation = Quaternion.Euler(Mathf.Lerp(-75f, 0f - Plugin.BroomPitch.Value, num), 0f, 0f);
				}
				else if (Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.GetTimeSeconds() < (double)sweepUntil)
				{
					broom.SetActive(true);
					float time = Time.time;
					broom.transform.localScale = Vector3.one;
					broom.transform.localPosition = new Vector3(0.25f + Mathf.Sin(time * 5f) * 0.35f, 0.85f, 0.75f);
					broom.transform.localRotation = Quaternion.Euler(-78f + Mathf.Sin(time * 10f) * 8f, Mathf.Sin(time * 5f) * 30f, Mathf.Sin(time * 23f) * 6f);
				}
				else if (since < 0.3f)
				{
					float num2 = since / 0.3f;
					broom.transform.localPosition = Vector3.Lerp(value2, val2, num2);
					broom.transform.localRotation = Quaternion.Euler(Mathf.Lerp(0f - Plugin.BroomPitch.Value, -75f, num2), 0f, 0f);
					broom.transform.localScale = Vector3.one * (1f - num2);
				}
				else
				{
					broom.SetActive(false);
				}
				if (riding)
				{
					broom.transform.localScale = Vector3.one;
				}
			}
		}

		private static GameObject Build(Transform parent)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Expected O, but got Unknown
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Expected O, but got Unknown
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b0: 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_02e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Expected O, but got Unknown
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_0178: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//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_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: 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_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_021b: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0229: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0325: Unknown result type (might be due to invalid IL or missing references)
			//IL_032c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0347: 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_035b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0362: Expected O, but got Unknown
			//IL_0394: Unknown result type (might be due to invalid IL or missing references)
			//IL_0399: 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_03a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_03ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_02df: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Unknown result type (might be due to invalid IL or missing references)
			//IL_031c: Unknown result type (might be due to invalid IL or missing references)
			//IL_023e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0243: Unknown result type (might be due to invalid IL or missing references)
			//IL_024c: Unknown result type (might be due to invalid IL or missing references)
			//IL_024e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0253: Unknown result type (might be due to invalid IL or missing references)
			//IL_026e: 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_025d: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = (Object.op_Implicit((Object)(object)ObjectDB.instance) ? ObjectDB.instance.GetItemPrefab("TrophyKvastur") : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			GameObject val2 = new GameObject("KvasturBroom_visual");
			GameObject val3 = new GameObject("modelo");
			val3.transform.SetParent(val2.transform, false);
			Bounds val4 = default(Bounds);
			bool flag = false;
			Renderer[] componentsInChildren = val.GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val5 in componentsInChildren)
			{
				Mesh val6 = null;
				SkinnedMeshRenderer val7 = (SkinnedMeshRenderer)(object)((val5 is SkinnedMeshRenderer) ? val5 : null);
				if (val7 != null)
				{
					val6 = val7.sharedMesh;
				}
				else if (val5 is MeshRenderer)
				{
					MeshFilter component = ((Component)val5).GetComponent<MeshFilter>();
					if (Object.op_Implicit((Object)(object)component))
					{
						val6 = component.sharedMesh;
					}
				}
				if (!Object.op_Implicit((Object)(object)val6))
				{
					continue;
				}
				GameObject val8 = new GameObject(((Object)val5).name);
				val8.transform.SetParent(val3.transform, false);
				val8.transform.position = val.transform.InverseTransformPoint(((Component)val5).transform.position);
				val8.transform.rotation = Quaternion.Inverse(val.transform.rotation) * ((Component)val5).transform.rotation;
				val8.transform.localScale = ((Component)val5).transform.lossyScale;
				val8.AddComponent<MeshFilter>().sharedMesh = val6;
				((Renderer)val8.AddComponent<MeshRenderer>()).sharedMaterials = val5.sharedMaterials;
				Vector3[] array = new Vector3[4];
				Bounds bounds = val6.bounds;
				array[0] = ((Bounds)(ref bounds)).min;
				bounds = val6.bounds;
				array[1] = ((Bounds)(ref bounds)).max;
				bounds = val6.bounds;
				float x = ((Bounds)(ref bounds)).min.x;
				bounds = val6.bounds;
				float y = ((Bounds)(ref bounds)).max.y;
				bounds = val6.bounds;
				array[2] = new Vector3(x, y, ((Bounds)(ref bounds)).min.z);
				bounds = val6.bounds;
				float x2 = ((Bounds)(ref bounds)).max.x;
				bounds = val6.bounds;
				float y2 = ((Bounds)(ref bounds)).min.y;
				bounds = val6.bounds;
				array[3] = new Vector3(x2, y2, ((Bounds)(ref bounds)).max.z);
				Vector3[] array2 = (Vector3[])(object)array;
				foreach (Vector3 val9 in array2)
				{
					Vector3 val10 = val8.transform.TransformPoint(val9);
					if (!flag)
					{
						((Bounds)(ref val4))..ctor(val10, Vector3.zero);
						flag = true;
					}
					else
					{
						((Bounds)(ref val4)).Encapsulate(val10);
					}
				}
			}
			if (!flag)
			{
				Object.Destroy((Object)(object)val2);
				return null;
			}
			Vector3 size = ((Bounds)(ref val4)).size;
			Quaternion val11 = Quaternion.identity;
			if (size.y >= size.x && size.y >= size.z)
			{
				val11 = Quaternion.Euler(90f, 0f, 0f);
			}
			else if (size.x >= size.y && size.x >= size.z)
			{
				val11 = Quaternion.Euler(0f, 90f, 0f);
			}
			float num = Mathf.Max(size.x, Mathf.Max(size.y, size.z));
			val3.transform.localPosition = -((Bounds)(ref val4)).center;
			GameObject val12 = new GameObject("pivo");
			val12.transform.SetParent(val2.transform, false);
			val3.transform.SetParent(val12.transform, false);
			val12.transform.localRotation = Quaternion.Euler(Plugin.BroomRotation.Value) * val11;
			val12.transform.localScale = Vector3.one * (Plugin.BroomLength.Value / Mathf.Max(0.01f, num));
			val2.transform.SetParent(parent, false);
			val2.transform.localPosition = Plugin.BroomOffset.Value;
			return val2;
		}
	}
	[HarmonyPatch(typeof(Player), "OnSpawned")]
	internal static class ResumeOnSpawnPatch
	{
		private static void Postfix(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				Mind.MigrateKeys(__instance);
				if (__instance.m_customData.TryGetValue("kvasturbroom_mounted", out var value) && value == "1")
				{
					Broom.Resume(__instance);
				}
			}
		}
	}
	internal static class Falas
	{
		internal const string Recusa = "Refuse";

		internal const string Emburrada = "Sulking";

		internal const string Insistindo = "Insisting";

		internal const string MuitoPeso = "TooHeavy";

		internal const string PesoAbsurdo = "WayTooHeavy";

		internal const string Cansada = "Tired";

		internal const string Irritada = "Irritated";

		internal const string Chuva = "Rain";

		internal const string Seco = "DryLand";

		internal const string Combate = "BeforeCombat";

		internal const string Rara = "Rare";

		internal const string SemClima = "NotInTheMood";

		internal const string Cansaco = "TiredOfYou";

		internal const string Calma = "CalmFlight";

		internal const string SemEitr = "NoEitrNervous";

		internal const string Calor = "Ashlands";

		internal const string Metal = "Metal";

		internal const string Ferida = "Wounded";

		internal const string Forcando = "Forcing";

		internal const string AvisoLargar = "DropWarning";

		internal const string Distraida = "Distracted";

		internal const string Ignorando = "NotWorthIt";

		private static readonly Dictionary<string, ConfigEntry<string>> en = new Dictionary<string, ConfigEntry<string>>();

		private static readonly Dictionary<string, ConfigEntry<string>> pt = new Dictionary<string, ConfigEntry<string>>();

		private static readonly Dictionary<string, float> lastSaid = new Dictionary<string, float>();

		private static float lastAny = -99f;

		internal static ConfigEntry<bool> On;

		internal static void Bind(ConfigFile cfg)
		{
			On = Plugin.B(cfg, "Lines", "Enabled", def: true, "The Kvastur talks in the situations below, in a bubble above her head. Each entry can hold several lines separated by | (she picks one at random).", "A Kvastur fala nas situações abaixo, num balão em cima da cabeça. Cada entrada pode ter várias frases separadas por | (ela sorteia uma).");
			Add(cfg, "Refuse", "Don't even think about it.", "Nem pense nisso.", "When she refuses to fly (patience almost at zero).", "Quando ela se recusa a voar (paciência quase zerada).");
			Add(cfg, "Sulking", "I need to put a few things back in place.", "Preciso colocar algumas coisas no lugar.", "When you insist and she gets sulky and goes off to sweep.", "Quando você insiste e ela fica emburrada e vai varrer.");
			Add(cfg, "Insisting", "You're still here, messing up my path?", "Você continua aqui, sujando meu caminho?", "When you keep insisting while she is sulking.", "Quando você continua insistindo enquanto ela está emburrada.");
			Add(cfg, "NotInTheMood", "Today I just want to stay home!", "Hoje só quero ficar em casa!", "When she just doesn't feel like flying (random roll) and sweeps the air.", "Quando ela simplesmente não quer voar (sorteio) e fica varrendo o ar.");
			Add(cfg, "TiredOfYou", "You again?", "Você de novo?", "When mounting with low patience (she flies slower).", "Ao montar com a paciência baixa (ela voa mais devagar).");
			Add(cfg, "TooHeavy", "I'm a broom, not a cart.|Better empty your pockets if you want to ride.", "Eu sou uma vassoura, não um carrinho.|Melhor esvaziar os bolsos se quiser montar.", "Heavy inventory: she flies slower and tires faster.", "Inventário pesado: ela voa mais devagar e cansa mais.");
			Add(cfg, "WayTooHeavy", "What you need is a Megingjord, not me.", "Você precisa é de um Megingjord, não de mim.", "Inventory over your carry capacity: she won't take off.", "Inventário acima da sua capacidade de carga: ela não decola.");
			Add(cfg, "Tired", "I'm starting to miss the ground.", "Estou começando a sentir saudade do chão.", "When her stamina drops below a quarter.", "Quando o fôlego dela cai abaixo de um quarto.");
			Add(cfg, "Irritated", "Don't test my patience.", "Não teste minha paciência.", "When her patience drops below 40.", "Quando a paciência cai abaixo de 40.");
			Add(cfg, "Forcing", "Everyone has a limit.", "Todo mundo tem um limite.", "When you push her (accelerate or climb) while she is exhausted.", "Quando você força (acelera ou sobe) com ela exausta.");
			Add(cfg, "DropWarning", "If you fall, I'm not sweeping you up with a dustpan.|Don't make me sweep you out of here.", "Se cair, eu não vou te juntar com a pá.|Não me faça varrer você daqui.", "When she starts thrashing, a few seconds before dropping you.", "Quando ela começa a se debater, alguns segundos antes de te largar.");
			Add(cfg, "Rain", "Listen... the sky is sweeping itself.|This rain makes me homesick.", "Escuta... é o céu varrendo a si mesmo.|Essa chuva me dá saudades de casa.", "When it rains while you fly (when you mount in the rain, and again every few minutes of rain). In the rain she flies faster, uses less stamina and loses no patience.", "Quando chove com você voando (ao montar na chuva e de novo a cada alguns minutos de chuva). Na chuva ela voa mais rápido, gasta menos fôlego e não perde paciência.");
			Add(cfg, "Wounded", "I'm broken.", "Estou quebrada.", "When you try to mount her while she is wounded (the only thing she says until she heals).", "Quando você tenta montar com ela ferida (a única coisa que ela diz até se curar).");
			Add(cfg, "Metal", "I think you'd better carry that some other way.", "Acho melhor você levar isso de outra forma.", "When you try to fly with metal (anything that can't go through a portal), or pick it up in the air.", "Quando você tenta voar com metal (nada que não passe no portal), ou pega no ar.");
			Add(cfg, "Ashlands", "Too hot.|Did you forget I'm made of straw and wood?", "Quente demais.|Esqueceu que sou feita de palha e madeira?", "Over the Ashlands, or when you try to take off there (she is afraid of the heat).", "Sobre as Cinzas, ou quando você tenta decolar lá (ela tem medo do calor).");
			Add(cfg, "Distracted", "This calls for a cleanup.", "Isso pede uma limpeza.", "When she spots an enemy and gets distracted, pulling toward it.", "Quando ela vê um inimigo e se distrai, puxando para ele.");
			Add(cfg, "NotWorthIt", "I prefer problems that fit in a dustpan.", "Eu prefiro problemas que caibam numa pá.", "When the distraction passes and she lets the enemy go.", "Quando a distração passa e ela deixa o inimigo para lá.");
			Add(cfg, "BeforeCombat", "I'll sweep you off the map.|I'll sort this out in a single sweep.", "Vou te varrer do mapa.|Eu resolvo isso numa varrida só.", "When she jumps off to fight.", "Quando ela pula para lutar.");
			Add(cfg, "Rare", "I miss the days when I just swept.", "Sinto falta de quando eu só varria.", "Rare line, every now and then, while flying.", "Fala rara, de vez em quando, voando.");
			Add(cfg, "NoEitrNervous", "I need some time to recover.", "Preciso de um tempo pra me recuperar.", "When she is out of stamina and you are out of eitr (she gets nervous and may drop you).", "Quando ela está sem fôlego e você sem eitr (ela fica nervosa e pode te largar).");
			Add(cfg, "CalmFlight", "Everything looks cleaner up here.|Relax, I know the way.|Flying is almost as good as sweeping.|The wind is on my side today.", "Aqui de cima tudo parece mais limpo.|Pode relaxar, eu conheço o caminho.|Voar é quase tão bom quanto varrer.|O vento hoje está do meu lado.", "Relaxed lines when the flight is going smoothly (calm, with stamina, no enemy nearby).", "Frases tranquilas quando ela está voando de boa (calma, com fôlego, sem inimigo por perto).");
		}

		private static void Add(ConfigFile cfg, string key, string defEn, string defPt, string descEn, string descPt)
		{
			en[key] = Plugin.B(cfg, "Lines", key, defEn, descEn, descPt);
			pt[key] = Plugin.B(cfg, "Lines PT-BR", key, defPt, descEn + " Portuguese version of the line.", descPt + " Versão em português da fala.");
		}

		internal static bool Say(GameObject who, string key, float cooldown = 60f, float height = 2.4f)
		{
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			if (On == null || !On.Value || !Object.op_Implicit((Object)(object)who) || (Object)(object)Chat.instance == (Object)null || (Mind.Wounded && key != "Wounded"))
			{
				return false;
			}
			ConfigEntry<string> value = null;
			if (L.IsPT)
			{
				pt.TryGetValue(key, out value);
			}
			if (value == null || string.IsNullOrEmpty(value.Value))
			{
				en.TryGetValue(key, out value);
			}
			if (value == null || string.IsNullOrEmpty(value.Value))
			{
				return false;
			}
			if (lastSaid.TryGetValue(key, out var value2) && Time.time - value2 < cooldown)
			{
				return false;
			}
			if (Time.time - lastAny < 4f)
			{
				return false;
			}
			lastSaid[key] = Time.time;
			lastAny = Time.time;
			string[] array = value.Value.Split('|');
			string text = array[Random.Range(0, array.Length)].Trim();
			if (text.Length == 0)
			{
				return false;
			}
			Chat.instance.SetNpcText(who, Vector3.up * height, 30f, 5f, Localization.instance.Localize("$enemy_kvastur"), text, false);
			return true;
		}
	}
	internal static class L
	{
		private static readonly Dictionary<string, string[]> T_ = new Dictionary<string, string[]>
		{
			{
				"hover_busy",
				new string[2] { "Busy", "Ocupada" }
			},
			{
				"st_calm",
				new string[2] { "Calm", "Calma" }
			},
			{
				"st_impatient",
				new string[2] { "Impatient", "Impaciente" }
			},
			{
				"st_exhausted",
				new string[2] { "Exhausted", "Exausta" }
			},
			{
				"st_nervous",
				new string[2] { "Nervous", "Nervosa" }
			},
			{
				"describe",
				new string[2] { "patience {0:0}/100, stamina {1:0}/{2:0}, health {3:0}, mood {4}", "paciência {0:0}/100, fôlego {1:0}/{2:0}, vida {3:0}, humor {4}" }
			},
			{
				"describe_sulk",
				new string[2] { ", sulking for {0} s", ", emburrada por {0} s" }
			},
			{
				"describe_nomood",
				new string[2] { ", not in the mood for {0} s", ", sem clima por {0} s" }
			},
			{
				"describe_mounted",
				new string[2] { ", mounted", ", montada" }
			},
			{
				"c_pose_saved",
				new string[2] { "Pose saved: {0}", "Pose guardada: {0}" }
			},
			{
				"c_poses",
				new string[2] { "Poses: {0}", "Poses: {0}" }
			},
			{
				"c_pose_missing",
				new string[2] { "Pose {0} not found.", "Não achei a pose {0}." }
			},
			{
				"c_pose_loaded",
				new string[2] { "Loaded {0} ({1} settings).", "Carreguei {0} ({1} ajustes)." }
			},
			{
				"h_save",
				new string[2] { "name: saves the current broom pose (hands, body, legs...) under that name", "nome: guarda a pose atual da vassoura (mãos, corpo, pernas...) com esse nome" }
			},
			{
				"h_load",
				new string[2] { "name: goes back to a saved pose (no name: lists the saved ones)", "nome: volta para uma pose guardada (sem nome: lista as guardadas)" }
			},
			{
				"h_state",
				new string[2] { "shows the Kvastur's patience, stamina, health and mood", "mostra a paciência, o fôlego, a vida e o humor da Kvastur" }
			},
			{
				"h_calm",
				new string[2] { "makes the Kvastur calm and rested (full patience and stamina, no sulking), for testing", "deixa a Kvastur calma e descansada (paciência e fôlego cheios, sem birra) para testar" }
			},
			{
				"t_header",
				new string[2] { "Kvastur tuning — ↑↓ select · ←→ change · Shift fine · R default · {0} close", "Ajuste da Kvastur — ↑↓ escolhe · ←→ muda · Shift fino · R padrão · {0} fecha" }
			},
			{
				"t_saved",
				new string[2] { "Saved to the cfg instantly.", "Grava no cfg na hora." }
			},
			{
				"t_mount",
				new string[2] { "Mount the broom to see the changes.", "Monte na vassoura para ver as mudanças." }
			},
			{
				"t_rider_h",
				new string[2] { "Rider: height on the broom (broom up/down)", "Personagem: altura na vassoura (vassoura sobe/desce)" }
			},
			{
				"t_rider_z",
				new string[2] { "Rider: forward/back on the broom", "Personagem: frente/trás na vassoura" }
			},
			{
				"t_rider_x",
				new string[2] { "Rider: sideways on the broom", "Personagem: lado na vassoura" }
			},
			{
				"t_lean",
				new string[2] { "Body: forward lean", "Corpo: inclinação para a frente" }
			},
			{
				"t_lean_side",
				new string[2] { "Body: side lean", "Corpo: inclinação para o lado" }
			},
			{
				"t_lean_twist",
				new string[2] { "Body: torso twist", "Corpo: giro do tronco" }
			},
			{
				"t_leg_hip",
				new string[2] { "Legs: raise thighs", "Pernas: levantar coxas" }
			},
			{
				"t_leg_in",
				new string[2] { "Legs: knees inward", "Pernas: joelhos para dentro" }
			},
			{
				"t_leg_spread",
				new string[2] { "Legs: rotate thighs", "Pernas: girar coxas" }
			},
			{
				"t_leg_knee",
				new string[2] { "Legs: bend knees", "Pernas: dobrar joelhos" }
			},
			{
				"t_leg_foot",
				new string[2] { "Legs: toe tips", "Pernas: ponta dos pés" }
			},
			{
				"t_elbow_r",
				new string[2] { "Right arm: elbow", "Braço direito: cotovelo" }
			},
			{
				"t_elbow_l",
				new string[2] { "Left arm: elbow", "Braço esquerdo: cotovelo" }
			},
			{
				"t_hr_z",
				new string[2] { "Right hand: forward/back on the shaft", "Mão direita: frente/trás no cabo" }
			},
			{
				"t_hr_y",
				new string[2] { "Right hand: height", "Mão direita: altura" }
			},
			{
				"t_hr_x",
				new string[2] { "Right hand: sideways", "Mão direita: lado" }
			},
			{
				"t_hr_roll",
				new string[2] { "Right hand: roll around the shaft", "Mão direita: giro em volta do cabo" }
			},
			{
				"t_hr_rx",
				new string[2] { "Right hand: bend up/down", "Mão direita: dobrar para cima/baixo" }
			},
			{
				"t_hr_ry",
				new string[2] { "Right hand: turn in/out", "Mão direita: virar para dentro/fora" }
			},
			{
				"t_hr_rz",
				new string[2] { "Right hand: twist around the arm", "Mão direita: girar em volta do braço" }
			},
			{
				"t_hl_z",
				new string[2] { "Left hand: forward/back on the shaft", "Mão esquerda: frente/trás no cabo" }
			},
			{
				"t_hl_y",
				new string[2] { "Left hand: height", "Mão esquerda: altura" }
			},
			{
				"t_hl_x",
				new string[2] { "Left hand: sideways", "Mão esquerda: lado" }
			},
			{
				"t_hl_roll",
				new string[2] { "Left hand: roll around the shaft", "Mão esquerda: giro em volta do cabo" }
			},
			{
				"t_hl_rx",
				new string[2] { "Left hand: bend up/down", "Mão esquerda: dobrar para cima/baixo" }
			},
			{
				"t_hl_ry",
				new string[2] { "Left hand: turn in/out", "Mão esquerda: virar para dentro/fora" }
			},
			{
				"t_hl_rz",
				new string[2] { "Left hand: twist around the arm", "Mão esquerda: girar em volta do braço" }
			},
			{
				"t_fingers",
				new string[2] { "Fingers: how much they close", "Dedos: quanto fecham" }
			},
			{
				"t_thumb",
				new string[2] { "Thumb: how much it closes", "Polegar: quanto fecha" }
			},
			{
				"t_cape_wind",
				new string[2] { "Cape: flight wind", "Capa: vento do voo" }
			},
			{
				"t_cape_flutter",
				new string[2] { "Cape: wind gusts", "Capa: rajadas do vento" }
			},
			{
				"t_pitch",
				new string[2] { "Broom: tip raised", "Vassoura: ponta levantada" }
			}
		};

		internal static bool IsPT
		{
			get
			{
				string text = null;
				try
				{
					if (Localization.instance != null)
					{
						text = Localization.instance.GetSelectedLanguage();
					}
				}
				catch
				{
				}
				if (string.IsNullOrEmpty(text))
				{
					text = PlayerPrefs.GetString("language", "English");
				}
				return text == "Portuguese_Brazilian";
			}
		}

		internal static string T(string key, params object[] args)
		{
			if (!T_.TryGetValue(key, out var value))
			{
				return key;
			}
			string text = ((IsPT && !string.IsNullOrEmpty(value[1])) ? value[1] : value[0]);
			if (args != null && args.Length != 0)
			{
				return string.Format(CultureInfo.InvariantCulture, text, args);
			}
			return text;
		}

		internal static string En(string key)
		{
			if (!T_.TryGetValue(key, out var value))
			{
				return key;
			}
			return value[0];
		}

		internal static string Pt(string key)
		{
			if (!T_.TryGetValue(key, out var value))
			{
				return key;
			}
			return value[1];
		}

		internal static void Check()
		{
			foreach (KeyValuePair<string, string[]> item in T_)
			{
				if (item.Value.Length != 2 || string.IsNullOrEmpty(item.Value[0]) || string.IsNullOrEmpty(item.Value[1]))
				{
					Plugin.Log.LogWarning((object)("Missing translation for text " + item.Key));
				}
			}
		}
	}
	internal static class Mind
	{
		internal static float Stamina = -1f;

		internal static float Mood = -1f;

		internal static float Health = -1f;

		internal static Character Provoker;

		private static float effort;

		private static float regenDelay;

		private static float lastRefuse = -99f;

		private static float sulkUntil = -99f;

		private static float nextChecks;

		private static float nextRare;

		private static int refuses;

		private static bool wasTired;

		private static bool wasIrritated;

		private static bool wasWet;

		private static Biome lastBiome;

		internal static bool Heavy;

		internal static bool NoEitr;

		private static bool wasNervous;

		private static float nextNervousCheck;

		private static float temper = 1f;

		private static float nextCalm;

		private static float ashT;

		private static float nextMoodCheck;

		private static float nextRainLine;

		private static bool wasAsh;

		private static string moodState = "st_calm";

		private static float noMoodUntil = -99f;

		internal static bool Exhausted;

		internal static string State = "st_calm";

		private static Character target;

		private static float distractT;

		private static float nextScan;

		private static float nextQuitCheck;

		private static float quitWarnT = -1f;

		private static float nextSave;

		private const string KS = "kvasturbroom_stamina";

		private const string KM = "kvasturbroom_patience";

		private const string KH = "kvasturbroom_health";

		private static readonly string[][] OldKeys = new string[4][]
		{
			new string[2] { "vassourakvastur_estamina", "kvasturbroom_stamina" },
			new string[2] { "vassourakvastur_paciencia", "kvasturbroom_patience" },
			new string[2] { "vassourakvastur_vida", "kvasturbroom_health" },
			new string[2] { "vassourakvastur_montada", "kvasturbroom_mounted" }
		};

		private static Player loadedFor;

		internal static bool Diving
		{
			get
			{
				if (Object.op_Implicit((Object)(object)Provoker))
				{
					return !Provoker.IsDead();
				}
				return false;
			}
		}

		internal static bool Nervous
		{
			get
			{
				if (Plugin.PersonalityOn.Value && Plugin.TNervous.Value && Plugin.UseEitr.Value && Exhausted)
				{
					return NoEitr;
				}
				return false;
			}
		}

		internal static bool Sulking
		{
			get
			{
				if (Plugin.PersonalityOn.Value)
				{
					return Time.time < sulkUntil;
				}
				return false;
			}
		}

		internal static float MaxHealth => Mathf.Max(1f, Plugin.MaxHealthCfg.Value);

		internal static bool Wounded
		{
			get
			{
				if (Plugin.TWounded.Value && Health >= 0f)
				{
					return Health < MaxHealth * Plugin.WoundedFraction.Value;
				}
				return false;
			}
		}

		internal static bool Warning
		{
			get
			{
				if (Plugin.PersonalityOn.Value)
				{
					return quitWarnT >= 0f;
				}
				return false;
			}
		}

		private static bool Swamp(Player p)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			if (Plugin.TSwamp.Value)
			{
				return (int)p.GetCurrentBiome() == 2;
			}
			return false;
		}

		private static bool Ash(Player p)
		{
			//IL_0019: Unknown result type (might be d