Decompiled source of WiresSmoothUI v0.2.3

WiresSmoothUI.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("WiresSmoothUI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("WiresSmoothUI")]
[assembly: AssemblyTitle("WiresSmoothUI")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace WiresSmoothUI
{
	internal static class BuildMenuAnimationSystem
	{
		private sealed class State
		{
			internal Transform Root;

			internal Transform Parent;

			internal Button Button;

			internal Vector3 BasePosition;

			internal Vector3 BaseScale;

			internal Quaternion BaseRotation;

			internal Vector3 AppliedPosition;

			internal float AppliedScale = 1f;

			internal float AppliedRotation;

			internal bool Applied;

			internal bool Hovered;

			internal bool Pressed;

			internal bool Selected;

			internal float Scale = 1f;

			internal Vector2 Sway;

			internal float Rotation;

			internal int ActiveIndex = -1;
		}

		private static readonly Dictionary<Transform, State> States = new Dictionary<Transform, State>();

		private static readonly List<State> Active = new List<State>();

		internal static bool OwnsButton(Button button)
		{
			if ((Object)(object)button == (Object)null)
			{
				return false;
			}
			if (!((Object)(object)((Component)button).GetComponentInParent<BuildUiPieceButton>() != (Object)null) && !((Object)(object)((Component)button).GetComponentInParent<BuildUiTagButton>() != (Object)null))
			{
				return (Object)(object)((Component)button).GetComponentInParent<BuildUiFavoriteCategoryCheckButton>() != (Object)null;
			}
			return true;
		}

		internal static void Register(Component owner)
		{
			if ((Object)(object)owner == (Object)null)
			{
				return;
			}
			Transform transform = owner.transform;
			if ((Object)(object)transform == (Object)null || States.ContainsKey(transform))
			{
				return;
			}
			Button component = owner.GetComponent<Button>();
			if (!((Object)(object)component == (Object)null))
			{
				ButtonAnimationSystem.Unregister(component);
				State state = new State
				{
					Root = transform,
					Button = component
				};
				CaptureBase(state);
				States.Add(transform, state);
				BuildMenuMotionHook buildMenuMotionHook = owner.GetComponent<BuildMenuMotionHook>();
				if ((Object)(object)buildMenuMotionHook == (Object)null)
				{
					buildMenuMotionHook = owner.gameObject.AddComponent<BuildMenuMotionHook>();
				}
				buildMenuMotionHook.Bind(transform);
			}
		}

		internal static void Unregister(Transform root)
		{
			if (!((Object)(object)root == (Object)null) && States.TryGetValue(root, out var value))
			{
				RestoreState(value);
				Deactivate(value);
				States.Remove(root);
			}
		}

		internal static void SetHovered(Transform root, bool value)
		{
			if (!((Object)(object)root == (Object)null) && States.TryGetValue(root, out var value2))
			{
				value2.Hovered = value && ZInput.instance != null && ZInput.IsMouseActive();
				if (!value2.Hovered)
				{
					value2.Pressed = false;
				}
				ActivateFresh(value2);
			}
		}

		internal static void SetPressed(Transform root, bool value)
		{
			if (!((Object)(object)root == (Object)null) && States.TryGetValue(root, out var value2))
			{
				value2.Pressed = value && value2.Hovered;
				ActivateFresh(value2);
			}
		}

		internal static void SetSelected(Transform root, bool value)
		{
			if (!((Object)(object)root == (Object)null) && States.TryGetValue(root, out var value2))
			{
				value2.Selected = value;
				ActivateFresh(value2);
			}
		}

		private static void ActivateFresh(State state)
		{
			//IL_001c: 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)
			if (state.ActiveIndex < 0)
			{
				CaptureBase(state);
				state.Scale = 1f;
				state.Sway = Vector2.zero;
				state.Rotation = 0f;
				state.ActiveIndex = Active.Count;
				Active.Add(state);
			}
		}

		internal static void Tick()
		{
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_0162: 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_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_0185: 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_0197: 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)
			if (!WiresSmoothUIPlugin.BuildMenuAnimations.Value)
			{
				RestoreAll();
			}
			else
			{
				if (Active.Count == 0)
				{
					return;
				}
				float num = Mathf.Max(1f, WiresSmoothUIPlugin.BuildMenuResponse.Value);
				float num2 = Mathf.Clamp(WiresSmoothUIPlugin.BuildMenuHoverScale.Value, 1f, 1.2f);
				float num3 = 1f + (num2 - 1f) * 0.75f;
				for (int num4 = Active.Count - 1; num4 >= 0; num4--)
				{
					State state = Active[num4];
					Transform root = state.Root;
					Button button = state.Button;
					if ((Object)(object)root == (Object)null || (Object)(object)button == (Object)null || !((Component)root).gameObject.activeInHierarchy)
					{
						RestoreState(state);
						DeactivateAt(num4);
					}
					else
					{
						RestoreState(state);
						bool flag = state.Hovered && ZInput.instance != null && ZInput.IsMouseActive();
						bool flag2 = state.Selected && ZInput.instance != null && ZInput.IsExclusiveGamepadActive();
						float target = 1f;
						if (state.Pressed && flag)
						{
							target = 0.965f;
						}
						else if (flag)
						{
							target = num2;
						}
						else if (flag2)
						{
							target = num3;
						}
						state.Scale = WiresSmoothUIPlugin.Damp(state.Scale, target, num);
						Vector2 target2 = Vector2.zero;
						float target3 = 0f;
						if (flag && WiresSmoothUIPlugin.BuildMenuInertia.Value)
						{
							Vector2 val = Vector2.ClampMagnitude(PointerMotion.Delta, 18f) / 18f;
							target2 = new Vector2(0f - val.x, 0f - val.y) * 1.65f;
							target3 = (0f - val.x) * 1.15f;
						}
						state.Sway = WiresSmoothUIPlugin.Damp(state.Sway, target2, num * 0.75f);
						state.Rotation = WiresSmoothUIPlugin.Damp(state.Rotation, target3, num * 0.7f);
						ApplyState(state);
						bool num5 = flag || flag2 || (state.Pressed && flag);
						bool flag3 = Mathf.Abs(state.Scale - 1f) < 0.001f && ((Vector2)(ref state.Sway)).sqrMagnitude < 0.0005f && Mathf.Abs(state.Rotation) < 0.01f;
						if (!num5 && flag3)
						{
							RestoreState(state);
							DeactivateAt(num4);
						}
					}
				}
			}
		}

		private static void ApplyState(State state)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//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)
			Transform root = state.Root;
			if (!((Object)(object)root == (Object)null))
			{
				Vector3 val = default(Vector3);
				((Vector3)(ref val))..ctor(state.Sway.x, state.Sway.y, 0f);
				root.localPosition = state.BasePosition + val;
				root.localScale = state.BaseScale * state.Scale;
				root.localRotation = state.BaseRotation * Quaternion.Euler(0f, 0f, state.Rotation);
				state.AppliedPosition = val;
				state.AppliedScale = state.Scale;
				state.AppliedRotation = state.Rotation;
				state.Applied = true;
			}
		}

		private static void CaptureBase(State state)
		{
			//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_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_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_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)state?.Root == (Object)null))
			{
				state.Parent = state.Root.parent;
				state.BasePosition = state.Root.localPosition;
				state.BaseScale = state.Root.localScale;
				state.BaseRotation = state.Root.localRotation;
				state.Applied = false;
				state.AppliedPosition = Vector3.zero;
				state.AppliedScale = 1f;
				state.AppliedRotation = 0f;
			}
		}

		private static void RestoreState(State state)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: 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_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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)
			if ((Object)(object)state?.Root == (Object)null || !state.Applied)
			{
				return;
			}
			Transform root = state.Root;
			if ((Object)(object)root.parent != (Object)(object)state.Parent)
			{
				CaptureBase(state);
				return;
			}
			Vector3 val = state.BasePosition + state.AppliedPosition;
			Vector3 val2 = state.BaseScale * state.AppliedScale;
			Quaternion val3 = state.BaseRotation * Quaternion.Euler(0f, 0f, state.AppliedRotation);
			Vector3 val4 = root.localPosition - val;
			if (((Vector3)(ref val4)).sqrMagnitude < 0.0009f)
			{
				root.localPosition = state.BasePosition;
			}
			else
			{
				state.BasePosition = root.localPosition;
			}
			val4 = root.localScale - val2;
			if (((Vector3)(ref val4)).sqrMagnitude < 0.0009f)
			{
				root.localScale = state.BaseScale;
			}
			else
			{
				state.BaseScale = root.localScale;
			}
			if (Quaternion.Angle(root.localRotation, val3) < 0.05f)
			{
				root.localRotation = state.BaseRotation;
			}
			else
			{
				state.BaseRotation = root.localRotation;
			}
			state.Applied = false;
			state.AppliedPosition = Vector3.zero;
			state.AppliedScale = 1f;
			state.AppliedRotation = 0f;
		}

		private static void Deactivate(State state)
		{
			if (state.ActiveIndex >= 0)
			{
				DeactivateAt(state.ActiveIndex);
			}
		}

		private static void DeactivateAt(int index)
		{
			int num = Active.Count - 1;
			State state = Active[index];
			if (index != num)
			{
				State state2 = Active[num];
				Active[index] = state2;
				state2.ActiveIndex = index;
			}
			Active.RemoveAt(num);
			state.ActiveIndex = -1;
		}

		internal static void RestoreAll()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			for (int num = Active.Count - 1; num >= 0; num--)
			{
				State state = Active[num];
				RestoreState(state);
				state.Hovered = false;
				state.Pressed = false;
				state.Selected = false;
				state.Scale = 1f;
				state.Sway = Vector2.zero;
				state.Rotation = 0f;
				DeactivateAt(num);
			}
		}

		internal static void Shutdown()
		{
			RestoreAll();
			States.Clear();
		}
	}
	internal sealed class BuildMenuMotionHook : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler, ISelectHandler, IDeselectHandler
	{
		private Transform _root;

		internal void Bind(Transform root)
		{
			_root = root;
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			BuildMenuAnimationSystem.SetHovered(_root, value: true);
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			BuildMenuAnimationSystem.SetHovered(_root, value: false);
		}

		public void OnPointerDown(PointerEventData eventData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if ((int)eventData.button == 0)
			{
				BuildMenuAnimationSystem.SetPressed(_root, value: true);
			}
		}

		public void OnPointerUp(PointerEventData eventData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if ((int)eventData.button == 0)
			{
				BuildMenuAnimationSystem.SetPressed(_root, value: false);
			}
		}

		public void OnSelect(BaseEventData eventData)
		{
			BuildMenuAnimationSystem.SetSelected(_root, value: true);
		}

		public void OnDeselect(BaseEventData eventData)
		{
			BuildMenuAnimationSystem.SetSelected(_root, value: false);
		}

		private void OnDisable()
		{
			BuildMenuAnimationSystem.SetHovered(_root, value: false);
			BuildMenuAnimationSystem.SetPressed(_root, value: false);
			BuildMenuAnimationSystem.SetSelected(_root, value: false);
		}

		private void OnDestroy()
		{
			BuildMenuAnimationSystem.Unregister(_root);
		}
	}
	[HarmonyPatch(typeof(BuildUiPieceButton), "Awake")]
	internal static class SmoothUIBuildPieceButtonPatch
	{
		[HarmonyPostfix]
		private static void Postfix(BuildUiPieceButton __instance)
		{
			BuildMenuAnimationSystem.Register((Component)(object)__instance);
		}
	}
	[HarmonyPatch(typeof(BuildUiTagButton), "Awake")]
	internal static class SmoothUIBuildTagButtonPatch
	{
		[HarmonyPostfix]
		private static void Postfix(BuildUiTagButton __instance)
		{
			BuildMenuAnimationSystem.Register((Component)(object)__instance);
		}
	}
	[HarmonyPatch(typeof(BuildUiFavoriteCategoryCheckButton), "Awake")]
	internal static class SmoothUIBuildFavoriteCheckPatch
	{
		[HarmonyPostfix]
		private static void Postfix(BuildUiFavoriteCategoryCheckButton __instance)
		{
			BuildMenuAnimationSystem.Register((Component)(object)__instance);
		}
	}
	internal static class ButtonAnimationSystem
	{
		internal sealed class State
		{
			internal Button Button;

			internal Vector3 BaseScale;

			internal float Scale = 1f;

			internal float AppliedScale = 1f;

			internal bool Applied;

			internal bool Hovered;

			internal bool Pressed;

			internal int ActiveIndex = -1;
		}

		private static readonly Dictionary<Button, State> States = new Dictionary<Button, State>();

		private static readonly List<State> Active = new List<State>();

		internal static void Register(Button button)
		{
			//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)
			if (!((Object)(object)button == (Object)null) && !States.ContainsKey(button) && !((Object)(object)((Component)button).GetComponentInParent<InventoryElement>() != (Object)null) && !((Object)(object)((Component)button).GetComponentInParent<InventoryGrid>() != (Object)null) && !((Object)(object)((Component)button).GetComponentInParent<HotkeyBar>() != (Object)null) && !BuildMenuAnimationSystem.OwnsButton(button))
			{
				State value = new State
				{
					Button = button,
					BaseScale = ((Component)button).transform.localScale
				};
				States.Add(button, value);
				ButtonMotionHook buttonMotionHook = ((Component)button).GetComponent<ButtonMotionHook>();
				if ((Object)(object)buttonMotionHook == (Object)null)
				{
					buttonMotionHook = ((Component)button).gameObject.AddComponent<ButtonMotionHook>();
				}
				buttonMotionHook.Bind(button);
			}
		}

		internal static void Unregister(Button button)
		{
			if (button != null && States.TryGetValue(button, out var value))
			{
				RestoreState(value);
				Deactivate(value);
				States.Remove(button);
			}
		}

		internal static void SetHovered(Button button, bool hovered)
		{
			if (!((Object)(object)button == (Object)null) && States.TryGetValue(button, out var value))
			{
				value.Hovered = hovered;
				if (!hovered)
				{
					value.Pressed = false;
				}
				if (WiresSmoothUIPlugin.ButtonAnimations.Value)
				{
					Activate(value);
				}
			}
		}

		internal static void SetPressed(Button button, bool pressed)
		{
			if (!((Object)(object)button == (Object)null) && States.TryGetValue(button, out var value))
			{
				value.Pressed = pressed;
				if (WiresSmoothUIPlugin.ButtonAnimations.Value)
				{
					Activate(value);
				}
			}
		}

		internal static void Tick()
		{
			//IL_0134: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			if (!WiresSmoothUIPlugin.ButtonAnimations.Value)
			{
				RestoreActive();
			}
			else
			{
				if (Active.Count == 0)
				{
					return;
				}
				for (int num = Active.Count - 1; num >= 0; num--)
				{
					State state = Active[num];
					Button button = state.Button;
					if ((Object)(object)button == (Object)null)
					{
						DeactivateAt(num);
					}
					else
					{
						RestoreState(state);
						if (!((Component)button).gameObject.activeInHierarchy || !((Selectable)button).interactable)
						{
							state.Hovered = false;
							state.Pressed = false;
						}
						float target = (state.Pressed ? 0.975f : (state.Hovered ? Mathf.Clamp(WiresSmoothUIPlugin.ButtonHoverScale.Value, 1f, 1.15f) : 1f));
						state.Scale = WiresSmoothUIPlugin.Damp(state.Scale, target, WiresSmoothUIPlugin.ButtonResponse.Value);
						if (!state.Hovered && !state.Pressed && Mathf.Abs(state.Scale - 1f) < 0.001f)
						{
							state.Scale = 1f;
							((Component)button).transform.localScale = state.BaseScale;
							DeactivateAt(num);
						}
						else
						{
							state.AppliedScale = state.Scale;
							((Component)button).transform.localScale = state.BaseScale * state.AppliedScale;
							state.Applied = true;
						}
					}
				}
			}
		}

		private static void RestoreState(State state)
		{
			//IL_0027: 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_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			if (state != null && !((Object)(object)state.Button == (Object)null) && state.Applied)
			{
				Transform transform = ((Component)state.Button).transform;
				Vector3 val = state.BaseScale * state.AppliedScale;
				Vector3 val2 = transform.localScale - val;
				if (((Vector3)(ref val2)).sqrMagnitude < 0.0009f)
				{
					transform.localScale = state.BaseScale;
				}
				else
				{
					state.BaseScale = transform.localScale;
				}
				state.Applied = false;
				state.AppliedScale = 1f;
			}
		}

		private static void Activate(State state)
		{
			if (state.ActiveIndex < 0)
			{
				state.ActiveIndex = Active.Count;
				Active.Add(state);
			}
		}

		private static void Deactivate(State state)
		{
			if (state.ActiveIndex >= 0)
			{
				DeactivateAt(state.ActiveIndex);
			}
		}

		private static void DeactivateAt(int index)
		{
			int num = Active.Count - 1;
			State state = Active[index];
			if (index != num)
			{
				State state2 = Active[num];
				Active[index] = state2;
				state2.ActiveIndex = index;
			}
			Active.RemoveAt(num);
			state.ActiveIndex = -1;
		}

		private static void RestoreActive()
		{
			for (int num = Active.Count - 1; num >= 0; num--)
			{
				State state = Active[num];
				RestoreState(state);
				state.Scale = 1f;
				state.Hovered = false;
				state.Pressed = false;
				DeactivateAt(num);
			}
		}

		internal static void RestoreAll()
		{
			RestoreActive();
		}

		internal static void Shutdown()
		{
			RestoreActive();
			States.Clear();
		}
	}
	internal sealed class ButtonMotionHook : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler
	{
		private Button _button;

		internal void Bind(Button button)
		{
			_button = button;
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			ButtonAnimationSystem.SetHovered(_button, hovered: true);
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			ButtonAnimationSystem.SetHovered(_button, hovered: false);
		}

		public void OnPointerDown(PointerEventData eventData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if ((int)eventData.button == 0)
			{
				ButtonAnimationSystem.SetPressed(_button, pressed: true);
			}
		}

		public void OnPointerUp(PointerEventData eventData)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			if ((int)eventData.button == 0)
			{
				ButtonAnimationSystem.SetPressed(_button, pressed: false);
			}
		}

		private void OnDisable()
		{
			ButtonAnimationSystem.SetHovered(_button, hovered: false);
			ButtonAnimationSystem.SetPressed(_button, pressed: false);
		}

		private void OnDestroy()
		{
			ButtonAnimationSystem.Unregister(_button);
		}
	}
	[HarmonyPatch(typeof(Selectable), "OnEnable")]
	internal static class SmoothUIButtonEnablePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Selectable __instance)
		{
			Button val = (Button)(object)((__instance is Button) ? __instance : null);
			if (val != null)
			{
				ButtonAnimationSystem.Register(val);
			}
		}
	}
	internal static class DragAnimationSystem
	{
		private static readonly FieldRef<InventoryGui, GameObject> DragGo = AccessTools.FieldRefAccess<InventoryGui, GameObject>("m_dragGo");

		private static GameObject _current;

		private static Vector3 _smoothPosition;

		private static Vector3 _baseScale = Vector3.one;

		private static Quaternion _baseRotation = Quaternion.identity;

		private static Vector2 _physicsOffset;

		private static Vector2 _physicsVelocity;

		private static float _rotation;

		private static float _rotationVelocity;

		private static float _spawnTimer;

		private static bool _applied;

		internal static bool IsDragging => (Object)(object)_current != (Object)null;

		internal static void NotifySetup(InventoryGui gui)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_00b1: 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_00c0: 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 ((Object)(object)gui == (Object)null)
			{
				return;
			}
			GameObject val;
			try
			{
				val = DragGo.Invoke(gui);
			}
			catch
			{
				return;
			}
			if ((Object)(object)val == (Object)null)
			{
				Restore();
				_current = null;
			}
			else if (!((Object)(object)_current == (Object)(object)val))
			{
				Restore();
				_current = val;
				_smoothPosition = ((ZInput.instance != null && ZInput.IsMouseActive()) ? ZInput.pointerPosition : val.transform.position);
				if (ZInput.instance != null && ZInput.IsMouseActive())
				{
					val.transform.position = _smoothPosition;
				}
				_baseScale = val.transform.localScale;
				_baseRotation = val.transform.localRotation;
				_physicsOffset = Vector2.zero;
				_physicsVelocity = Vector2.zero;
				_rotation = 0f;
				_rotationVelocity = 0f;
				_spawnTimer = 0f;
			}
		}

		internal static void Tick()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: 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_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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0284: Unknown result type (might be due to invalid IL or missing references)
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0293: Unknown result type (might be due to invalid IL or missing references)
			//IL_0298: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: 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_0104: 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_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: 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_0134: 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_014e: 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_015a: 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_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_024a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_026d: Unknown result type (might be due to invalid IL or missing references)
			GameObject current = _current;
			if ((Object)(object)current == (Object)null)
			{
				return;
			}
			if (_applied)
			{
				Vector3 val = _baseScale * CurrentScale();
				Quaternion val2 = _baseRotation * Quaternion.Euler(0f, 0f, _rotation);
				Vector3 val3 = current.transform.localScale - val;
				if (((Vector3)(ref val3)).sqrMagnitude > 0.0009f)
				{
					_baseScale = current.transform.localScale;
				}
				if (Quaternion.Angle(current.transform.localRotation, val2) > 0.05f)
				{
					_baseRotation = current.transform.localRotation;
				}
			}
			if (!WiresSmoothUIPlugin.ItemAnimations.Value)
			{
				Restore();
				return;
			}
			float dt = WiresSmoothUIPlugin.Dt;
			_spawnTimer += dt;
			if (ZInput.IsMouseActive())
			{
				Vector3 val4 = Vector2.op_Implicit(PointerMotion.Position);
				float num = Mathf.Max(1f, WiresSmoothUIPlugin.DragFollow.Value);
				float num2 = 1f - Mathf.Exp((0f - num) * dt);
				_smoothPosition = Vector3.Lerp(_smoothPosition, val4, num2);
				Vector2 val5 = Vector2.ClampMagnitude(PointerMotion.Delta, 24f);
				Vector2 val6 = (WiresSmoothUIPlugin.DragPhysics.Value ? (-val5 * 0.17f) : Vector2.zero);
				val6 = Vector2.ClampMagnitude(val6, 4.25f);
				float target = (WiresSmoothUIPlugin.DragPhysics.Value ? ((0f - Mathf.Clamp(val5.x / 18f, -1f, 1f)) * Mathf.Max(0f, WiresSmoothUIPlugin.DragRotation.Value)) : 0f);
				float num3 = Mathf.Clamp(num * 0.6f, 7f, 22f);
				_physicsOffset.x = Spring(_physicsOffset.x, ref _physicsVelocity.x, val6.x, num3, 0.68f, dt);
				_physicsOffset.y = Spring(_physicsOffset.y, ref _physicsVelocity.y, val6.y, num3, 0.68f, dt);
				_rotation = Spring(_rotation, ref _rotationVelocity, target, num3 * 0.8f, 0.62f, dt);
				current.transform.position = _smoothPosition + new Vector3(_physicsOffset.x, _physicsOffset.y, 0f);
			}
			else
			{
				_smoothPosition = current.transform.position;
				_physicsOffset = Vector2.zero;
				_physicsVelocity = Vector2.zero;
				_rotation = 0f;
				_rotationVelocity = 0f;
			}
			current.transform.localScale = _baseScale * CurrentScale();
			current.transform.localRotation = _baseRotation * Quaternion.Euler(0f, 0f, _rotation);
			_applied = true;
		}

		private static float Spring(float current, ref float velocity, float target, float frequency, float damping, float dt)
		{
			float num = Mathf.Max(1f, frequency);
			float num2 = (target - current) * num * num - 2f * damping * num * velocity;
			velocity += num2 * dt;
			return current + velocity * dt;
		}

		private static float CurrentScale()
		{
			float num = Mathf.Max(0.01f, WiresSmoothUIPlugin.ItemAppearDuration.Value);
			if (_spawnTimer >= num)
			{
				return 1f;
			}
			float num2 = Mathf.Clamp01(_spawnTimer / num);
			float num3 = WiresSmoothUIPlugin.PopScale(num2, 0.88f);
			float num4 = Mathf.Sin(num2 * (float)Math.PI) * 0.025f;
			return num3 + num4;
		}

		internal static void Restore()
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_001e: 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)
			if ((Object)(object)_current != (Object)null && _applied)
			{
				_current.transform.localScale = _baseScale;
				_current.transform.localRotation = _baseRotation;
			}
			_applied = false;
			_physicsOffset = Vector2.zero;
			_physicsVelocity = Vector2.zero;
			_rotation = 0f;
			_rotationVelocity = 0f;
		}
	}
	[HarmonyPatch(typeof(InventoryGui), "SetupDragItem")]
	internal static class SmoothUIDragSetupPatch
	{
		[HarmonyPostfix]
		private static void Postfix(InventoryGui __instance)
		{
			DragAnimationSystem.NotifySetup(__instance);
		}
	}
	internal sealed class DynamicReticleSystem : MonoBehaviour
	{
		private enum AttackGroup
		{
			None,
			Spear,
			Magic,
			Other
		}

		public enum EasingMode
		{
			Linear,
			SineInOut,
			ExpoInOut
		}

		[HarmonyPatch(typeof(Hud), "Awake")]
		private static class HudAwakePatch
		{
			[HarmonyPostfix]
			private static void Postfix(Hud __instance)
			{
				if ((Object)(object)__instance != (Object)null && (Object)(object)((Component)__instance).GetComponent<DynamicReticleSystem>() == (Object)null)
				{
					((Component)__instance).gameObject.AddComponent<DynamicReticleSystem>();
				}
			}
		}

		[HarmonyPatch(typeof(Hud), "UpdateCrosshair")]
		private static class HudUpdateCrosshairPatch
		{
			private static void Postfix(Hud __instance, Player player, float bowDrawPercentage)
			{
				if ((Object)(object)Instance != (Object)null)
				{
					Instance.UpdateHud(__instance, player, bowDrawPercentage);
				}
			}
		}

		[HarmonyPatch(typeof(Hud), "UpdateStealth")]
		private static class HudUpdateStealthPatch
		{
			private static void Postfix(Hud __instance)
			{
				DisableStealthHud(__instance);
			}
		}

		[HarmonyPatch(typeof(Attack), "Start")]
		private static class AttackStartPatch
		{
			private static void Postfix(Attack __instance, Humanoid character, ItemData weapon, ref bool __result)
			{
				if ((Object)(object)Instance != (Object)null)
				{
					Instance.OnAttackStarted(__instance, character, weapon, __result);
				}
			}
		}

		[HarmonyPatch(typeof(Attack), "OnAttackTrigger")]
		private static class AttackTriggerPatch
		{
			private static void Postfix(Attack __instance)
			{
				if ((Object)(object)Instance != (Object)null)
				{
					Instance.OnAttackTriggered(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Attack), "Stop")]
		private static class AttackStopPatch
		{
			private static void Postfix(Attack __instance)
			{
				if ((Object)(object)Instance != (Object)null)
				{
					Instance.OnAttackStopped(__instance);
				}
			}
		}

		private const float VanillaStartScale = 1f;

		private const float VanillaEndScale = 0.15f;

		private const float VanillaCrosshairIdleAlpha = 0.5f;

		internal static DynamicReticleSystem Instance;

		private Image _customRing;

		private Hud _customRingHud;

		private float _crosshairVisibility;

		private bool _bowReleaseWaitingForZero;

		private GameObject _lastHoverObject;

		private bool _lastHoverInteractable;

		private Attack _activeAttack;

		private ItemData _activeWeapon;

		private AttackGroup _activeGroup;

		private bool _activeReleased;

		private readonly Dictionary<string, float> _learnedReleaseTimes = new Dictionary<string, float>(StringComparer.Ordinal);

		private static readonly FieldRef<Player, List<MinorActionData>> ActionQueueRef = AccessTools.FieldRefAccess<Player, List<MinorActionData>>("m_actionQueue");

		private static readonly FieldRef<Attack, Humanoid> AttackCharacterRef = AccessTools.FieldRefAccess<Attack, Humanoid>("m_character");

		private static readonly FieldRef<Attack, float> AttackTimeRef = AccessTools.FieldRefAccess<Attack, float>("m_time");

		private void Awake()
		{
			Instance = this;
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		internal static void Shutdown()
		{
			DynamicReticleSystem instance = Instance;
			if (!((Object)(object)instance == (Object)null))
			{
				if ((Object)(object)instance._customRing != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)instance._customRing).gameObject);
				}
				instance._customRing = null;
				instance._customRingHud = null;
				instance._activeAttack = null;
				instance._activeWeapon = null;
				instance._activeGroup = AttackGroup.None;
				instance._activeReleased = false;
				instance._bowReleaseWaitingForZero = false;
				instance._crosshairVisibility = 0f;
				instance._lastHoverObject = null;
				instance._lastHoverInteractable = false;
			}
		}

		internal void UpdateHud(Hud hud, Player player, float bowDrawPercentage)
		{
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0114: Invalid comparison between Unknown and I4
			if ((Object)(object)hud == (Object)null || (Object)(object)player == (Object)null)
			{
				return;
			}
			if (!WiresSmoothUIPlugin.Enabled.Value || !WiresSmoothUIPlugin.CrosshairAnimations.Value)
			{
				if ((Object)(object)_customRing != (Object)null)
				{
					((Component)_customRing).gameObject.SetActive(false);
				}
				_crosshairVisibility = 0f;
				return;
			}
			EnsureCustomRing(hud);
			if ((Object)(object)hud.m_crosshairBow != (Object)null)
			{
				((Component)hud.m_crosshairBow).gameObject.SetActive(false);
			}
			ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon();
			ItemData rightItem = ((Humanoid)player).RightItem;
			ItemData leftItem = ((Humanoid)player).LeftItem;
			UpdateNormalCrosshair(hud, player, rightItem, leftItem);
			if (WiresSmoothUIPlugin.ProjectileReticle.Value && bowDrawPercentage > 0f)
			{
				if (_bowReleaseWaitingForZero)
				{
					HideRing(hud);
				}
				else
				{
					RenderProgress(hud, bowDrawPercentage, useConfiguredEasing: true);
				}
				return;
			}
			if (bowDrawPercentage <= 0f && _bowReleaseWaitingForZero)
			{
				_bowReleaseWaitingForZero = false;
			}
			if (!WiresSmoothUIPlugin.ProjectileReticle.Value)
			{
				HideRing(hud);
			}
			else if (currentWeapon == null || currentWeapon.m_shared == null)
			{
				HideRing(hud);
			}
			else if ((int)currentWeapon.m_shared.m_skillType == 14)
			{
				RenderCrossbow(hud, player, currentWeapon);
			}
			else if (IsDundr(currentWeapon))
			{
				RenderDundr(hud, player, currentWeapon);
			}
			else if (_activeAttack != null && _activeWeapon == currentWeapon)
			{
				RenderActiveAttack(hud);
			}
			else
			{
				HideRing(hud);
			}
		}

		private void UpdateNormalCrosshair(Hud hud, Player player, ItemData rightItem, ItemData leftItem)
		{
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: 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)
			Image crosshair = hud.m_crosshair;
			if ((Object)(object)crosshair == (Object)null)
			{
				return;
			}
			if (((Character)player).IsAttached() && (Object)(object)player.GetAttachCameraPoint() != (Object)null)
			{
				_crosshairVisibility = 0f;
				return;
			}
			bool flag = false;
			if (WiresSmoothUIPlugin.ShowHoverCrosshair.Value)
			{
				flag = (Object)(object)hud.m_hoverName != (Object)null && !string.IsNullOrEmpty(((TMP_Text)hud.m_hoverName).text);
				if (!flag)
				{
					GameObject hoverObject = ((Humanoid)player).GetHoverObject();
					if ((Object)(object)hoverObject != (Object)(object)_lastHoverObject)
					{
						_lastHoverObject = hoverObject;
						_lastHoverInteractable = false;
						if ((Object)(object)hoverObject != (Object)null)
						{
							try
							{
								_lastHoverInteractable = hoverObject.GetComponentInParent<Interactable>() != null;
							}
							catch
							{
								_lastHoverInteractable = false;
							}
						}
					}
					flag = _lastHoverInteractable;
				}
			}
			bool flag2 = (WiresSmoothUIPlugin.ShowHeldCrosshair.Value && (IsActualHeldWeaponOrTool(rightItem) || IsActualHeldWeaponOrTool(leftItem))) || flag;
			float num = Mathf.Max(0.001f, WiresSmoothUIPlugin.CrosshairFade.Value);
			_crosshairVisibility = Mathf.MoveTowards(_crosshairVisibility, flag2 ? 1f : 0f, Time.unscaledDeltaTime / num);
			Color color = ((Graphic)crosshair).color;
			float num2 = Mathf.Max(color.a, 0.5f);
			color.a = num2 * _crosshairVisibility;
			((Graphic)crosshair).color = color;
		}

		private static bool IsActualHeldWeaponOrTool(ItemData item)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Invalid comparison between Unknown and I4
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Invalid comparison between Unknown and I4
			if (item == null || item.m_shared == null)
			{
				return false;
			}
			if (item.IsWeapon())
			{
				return true;
			}
			ItemType itemType = item.m_shared.m_itemType;
			if ((int)itemType != 19)
			{
				return (int)itemType == 15;
			}
			return true;
		}

		private void RenderCrossbow(Hud hud, Player player, ItemData weapon)
		{
			if (TryGetReloadProgress(player, weapon, out var progress))
			{
				RenderProgress(hud, progress);
			}
			else if (((Humanoid)player).IsWeaponLoaded())
			{
				RenderProgress(hud, 1f);
			}
			else
			{
				HideRing(hud);
			}
		}

		private void RenderDundr(Hud hud, Player player, ItemData weapon)
		{
			if (TryGetReloadProgress(player, weapon, out var progress))
			{
				RenderProgress(hud, progress);
			}
			else if (((Humanoid)player).IsWeaponLoaded())
			{
				RenderProgress(hud, 1f);
			}
			else if (_activeAttack != null && _activeWeapon == weapon && !_activeReleased)
			{
				RenderActiveAttack(hud);
			}
			else
			{
				HideRing(hud);
			}
		}

		private bool TryGetReloadProgress(Player player, ItemData weapon, out float progress)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Invalid comparison between Unknown and I4
			progress = 0f;
			List<MinorActionData> list = ActionQueueRef.Invoke(player);
			if (list == null)
			{
				return false;
			}
			for (int i = 0; i < list.Count; i++)
			{
				MinorActionData val = list[i];
				if (val != null && (int)val.m_type == 2 && (val.m_item == null || val.m_item == weapon))
				{
					progress = ((val.m_duration <= 0f) ? 1f : Mathf.Clamp01(val.m_time / val.m_duration));
					return true;
				}
			}
			return false;
		}

		private void RenderActiveAttack(Hud hud)
		{
			if (_activeAttack == null)
			{
				HideRing(hud);
			}
			else if (_activeReleased)
			{
				if (IsSustainedBurstAttack(_activeAttack))
				{
					RenderProgress(hud, 1f);
				}
				else
				{
					HideRing(hud);
				}
			}
			else
			{
				float attackElapsed = GetAttackElapsed(_activeAttack);
				float expectedReleaseSeconds = GetExpectedReleaseSeconds(_activeAttack, _activeWeapon, _activeGroup);
				float rawProgress = ((expectedReleaseSeconds <= 0.001f) ? 0f : Mathf.Clamp01(attackElapsed / expectedReleaseSeconds));
				RenderProgress(hud, rawProgress);
			}
		}

		private void RenderProgress(Hud hud, float rawProgress)
		{
			RenderProgress(hud, rawProgress, useConfiguredEasing: true);
		}

		private void RenderProgress(Hud hud, float rawProgress, bool useConfiguredEasing)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			EnsureCustomRing(hud);
			if (!((Object)(object)_customRing == (Object)null))
			{
				rawProgress = Mathf.Clamp01(rawProgress);
				if (rawProgress <= 0f)
				{
					((Component)_customRing).gameObject.SetActive(false);
					return;
				}
				float num = (useConfiguredEasing ? Ease(rawProgress) : rawProgress);
				float num2 = Mathf.Lerp(GetStartScale(), GetEndScale(), num);
				((Component)_customRing).gameObject.SetActive(true);
				((Component)_customRing).transform.localScale = new Vector3(num2, num2, num2);
				((Graphic)_customRing).color = Color.Lerp(new Color(1f, 1f, 1f, 0f), Color.yellow, num);
			}
		}

		internal void OnAttackStarted(Attack attack, Humanoid character, ItemData weapon, bool started)
		{
			if (started && WiresSmoothUIPlugin.Enabled.Value && WiresSmoothUIPlugin.CrosshairAnimations.Value && attack != null && !((Object)(object)character != (Object)(object)Player.m_localPlayer) && weapon != null && weapon.m_shared != null)
			{
				AttackGroup attackGroup = ClassifyAttack(weapon, attack);
				if (attackGroup != AttackGroup.None)
				{
					_activeAttack = attack;
					_activeWeapon = weapon;
					_activeGroup = attackGroup;
					_activeReleased = false;
				}
			}
		}

		internal void OnAttackTriggered(Attack attack)
		{
			//IL_004a: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Invalid comparison between Unknown and I4
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006a: Invalid comparison between Unknown and I4
			if (!WiresSmoothUIPlugin.Enabled.Value || !WiresSmoothUIPlugin.CrosshairAnimations.Value || attack == null)
			{
				return;
			}
			Humanoid attackCharacter = GetAttackCharacter(attack);
			if ((Object)(object)attackCharacter != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			ItemData currentWeapon = attackCharacter.GetCurrentWeapon();
			if (currentWeapon == null || currentWeapon.m_shared == null)
			{
				return;
			}
			SkillType skillType = currentWeapon.m_shared.m_skillType;
			if ((int)skillType == 8)
			{
				HideRing(Hud.instance);
				_bowReleaseWaitingForZero = true;
			}
			else if ((int)skillType == 14)
			{
				HideRing(Hud.instance);
			}
			else if (attack == _activeAttack)
			{
				float attackElapsed = GetAttackElapsed(attack);
				if (attackElapsed > 0.03f && attackElapsed < 10f)
				{
					_learnedReleaseTimes[GetAttackKey(attack, _activeWeapon)] = attackElapsed;
				}
				_activeReleased = true;
				if (!IsSustainedBurstAttack(attack))
				{
					HideRing(Hud.instance);
				}
			}
		}

		internal void OnAttackStopped(Attack attack)
		{
			if (attack != null && attack == _activeAttack)
			{
				if (_activeReleased && IsSustainedBurstAttack(attack))
				{
					HideRing(Hud.instance);
				}
				_activeAttack = null;
				_activeWeapon = null;
				_activeGroup = AttackGroup.None;
				_activeReleased = false;
			}
		}

		private AttackGroup ClassifyAttack(ItemData weapon, Attack attack)
		{
			//IL_001b: 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_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Invalid comparison between Unknown and I4
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			if (weapon == null || weapon.m_shared == null || !IsProjectileAttack(attack))
			{
				return AttackGroup.None;
			}
			SkillType skillType = weapon.m_shared.m_skillType;
			if ((int)skillType == 8 || (int)skillType == 14)
			{
				return AttackGroup.None;
			}
			if ((int)skillType == 5)
			{
				return AttackGroup.Spear;
			}
			if (IsMagicSkill(skillType))
			{
				if (IsUtilityMagicStaff(weapon))
				{
					return AttackGroup.None;
				}
				return AttackGroup.Magic;
			}
			return AttackGroup.Other;
		}

		private bool IsRangedWeaponForCrosshair(ItemData weapon)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Invalid comparison between Unknown and I4
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Invalid comparison between Unknown and I4
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Invalid comparison between Unknown and I4
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (weapon == null || weapon.m_shared == null)
			{
				return false;
			}
			SkillType skillType = weapon.m_shared.m_skillType;
			if ((int)skillType == 8 || (int)skillType == 14 || (int)skillType == 5)
			{
				return true;
			}
			if (IsMagicSkill(skillType) && IsUtilityMagicStaff(weapon))
			{
				return false;
			}
			if (!IsProjectileAttack(weapon.m_shared.m_attack))
			{
				return IsProjectileAttack(weapon.m_shared.m_secondaryAttack);
			}
			return true;
		}

		private float GetExpectedReleaseSeconds(Attack attack, ItemData weapon, AttackGroup group)
		{
			string attackKey = GetAttackKey(attack, weapon);
			if (_learnedReleaseTimes.TryGetValue(attackKey, out var value) && value > 0.03f)
			{
				return value;
			}
			return group switch
			{
				AttackGroup.Spear => 0.55f, 
				AttackGroup.Magic => 0.42f, 
				_ => 0.4f, 
			};
		}

		private float GetScaleForRawProgress(float rawProgress)
		{
			float num = Ease(Mathf.Clamp01(rawProgress));
			return Mathf.Lerp(GetStartScale(), GetEndScale(), num);
		}

		private float GetStartScale()
		{
			return 1f;
		}

		private float GetEndScale()
		{
			return 0.15f;
		}

		private float Ease(float t)
		{
			t = Mathf.Clamp01(t);
			switch (WiresSmoothUIPlugin.ReticleEasing.Value)
			{
			case EasingMode.Linear:
				return t;
			case EasingMode.ExpoInOut:
				if (t <= 0f)
				{
					return 0f;
				}
				if (t >= 1f)
				{
					return 1f;
				}
				if (!(t < 0.5f))
				{
					return (2f - Mathf.Pow(2f, -20f * t + 10f)) / 2f;
				}
				return Mathf.Pow(2f, 20f * t - 10f) / 2f;
			default:
				return (0f - (Mathf.Cos((float)Math.PI * t) - 1f)) / 2f;
			}
		}

		private static bool IsSustainedBurstAttack(Attack attack)
		{
			if (attack != null)
			{
				return attack.m_projectileBursts > 1;
			}
			return false;
		}

		private static string GetAttackKey(Attack attack, ItemData weapon)
		{
			string text = ((weapon != null && weapon.m_shared != null) ? (weapon.m_shared.m_name ?? string.Empty) : string.Empty);
			string text2 = ((attack != null) ? (attack.m_attackAnimation ?? string.Empty) : string.Empty);
			return text + "|" + text2 + "|" + ((attack != null) ? ((object)Unsafe.As<AttackType, AttackType>(ref attack.m_attackType)/*cast due to .constrained prefix*/).ToString() : string.Empty);
		}

		private static float GetAttackElapsed(Attack attack)
		{
			if (attack != null)
			{
				return AttackTimeRef.Invoke(attack);
			}
			return 0f;
		}

		private static Humanoid GetAttackCharacter(Attack attack)
		{
			if (attack != null)
			{
				return AttackCharacterRef.Invoke(attack);
			}
			return null;
		}

		private static bool IsProjectileAttack(Attack attack)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Invalid comparison between Unknown and I4
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Invalid comparison between Unknown and I4
			if (attack != null)
			{
				if ((int)attack.m_attackType != 2)
				{
					return (int)attack.m_attackType == 5;
				}
				return true;
			}
			return false;
		}

		private static bool IsMagicSkill(SkillType skill)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Invalid comparison between Unknown and I4
			if ((int)skill != 9)
			{
				return (int)skill == 10;
			}
			return true;
		}

		private static bool IsDundr(ItemData weapon)
		{
			if (weapon != null && weapon.m_shared != null)
			{
				return string.Equals(weapon.m_shared.m_name, "$item_staff_lightning", StringComparison.OrdinalIgnoreCase);
			}
			return false;
		}

		private static bool IsUtilityMagicStaff(ItemData weapon)
		{
			if (weapon == null || weapon.m_shared == null)
			{
				return false;
			}
			switch ((weapon.m_shared.m_name ?? string.Empty).ToLowerInvariant())
			{
			case "$item_staffshield":
			case "$item_staffskeleton":
			case "$item_staffredtroll":
			case "$item_staff_frostorbs":
			case "$item_staff_spiritcaller":
				return true;
			default:
				return false;
			}
		}

		internal static void DisableStealthHud(Hud hud)
		{
			if (!((Object)(object)Instance == (Object)null) && WiresSmoothUIPlugin.Enabled.Value && WiresSmoothUIPlugin.CrosshairAnimations.Value && WiresSmoothUIPlugin.DisableStealthIndicator.Value && !((Object)(object)hud == (Object)null))
			{
				if ((Object)(object)hud.m_targetedAlert != (Object)null)
				{
					hud.m_targetedAlert.SetActive(false);
				}
				if ((Object)(object)hud.m_targeted != (Object)null)
				{
					hud.m_targeted.SetActive(false);
				}
				if ((Object)(object)hud.m_hidden != (Object)null)
				{
					hud.m_hidden.SetActive(false);
				}
				if ((Object)(object)hud.m_stealthBar != (Object)null)
				{
					((Component)hud.m_stealthBar).gameObject.SetActive(false);
				}
			}
		}

		private void EnsureCustomRing(Hud hud)
		{
			if (!((Object)(object)hud == (Object)null) && !((Object)(object)hud.m_crosshairBow == (Object)null) && (!((Object)(object)_customRing != (Object)null) || !((Object)(object)_customRingHud == (Object)(object)hud)))
			{
				if ((Object)(object)_customRing != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)_customRing).gameObject);
				}
				_customRingHud = hud;
				_customRing = Object.Instantiate<Image>(hud.m_crosshairBow, ((Component)hud.m_crosshairBow).transform.parent, false);
				((Object)_customRing).name = "DynamicReticleRing";
				((Graphic)_customRing).raycastTarget = false;
				((Component)_customRing).transform.SetSiblingIndex(((Component)hud.m_crosshairBow).transform.GetSiblingIndex() + 1);
				((Component)_customRing).gameObject.SetActive(false);
			}
		}

		private void HideRing(Hud hud)
		{
			if ((Object)(object)_customRing != (Object)null)
			{
				((Component)_customRing).gameObject.SetActive(false);
			}
		}
	}
	[HarmonyPatch(typeof(Hud), "Awake")]
	internal static class SmoothUIHudAwakePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Hud __instance)
		{
			if (!((Object)(object)__instance == (Object)null) && (Object)(object)((Component)__instance).GetComponent<DynamicReticleSystem>() == (Object)null)
			{
				((Component)__instance).gameObject.AddComponent<DynamicReticleSystem>();
			}
		}
	}
	internal static class ItemAnimationSystem
	{
		private sealed class RefComparer<T> : IEqualityComparer<T> where T : class
		{
			internal static readonly RefComparer<T> Instance = new RefComparer<T>();

			public bool Equals(T x, T y)
			{
				return x == y;
			}

			public int GetHashCode(T obj)
			{
				return RuntimeHelpers.GetHashCode(obj);
			}
		}

		private sealed class PartState
		{
			internal Transform Transform;

			internal Vector3 BasePosition;

			internal Vector3 BaseScale;

			internal Quaternion BaseRotation;

			internal Vector3 AppliedPosition;

			internal float AppliedScale = 1f;

			internal float AppliedRotation;

			internal bool Applied;
		}

		private sealed class ItemState
		{
			internal InventoryGrid Grid;

			internal GridContext Context;

			internal int ContextIndex = -1;

			internal int OccupiedIndex = -1;

			internal InventoryElement Element;

			internal ItemData Item;

			internal int Stack;

			internal int StackDirection;

			internal bool Equipped;

			internal bool Queued;

			internal bool HasStatusSnapshot;

			internal int Generation;

			internal readonly List<PartState> Parts = new List<PartState>(8);

			internal float AppearTimer = 999f;

			internal float MoveTimer = 999f;

			internal float PulseTimer = 999f;

			internal float EquipTimer = 999f;

			internal float QueueTimer = 999f;

			internal Vector3 MoveFromWorld;

			internal int ActiveIndex = -1;
		}

		private sealed class GridContext
		{
			internal InventoryGrid Grid;

			internal Inventory Inventory;

			internal Action ChangedHandler;

			internal readonly List<ItemState> States = new List<ItemState>();

			internal readonly List<ItemState> Occupied = new List<ItemState>();

			internal bool Dirty = true;

			internal int Generation;
		}

		private sealed class PositionRecord
		{
			internal Vector3 World;

			internal float LastSeen;
		}

		private static readonly FieldRef<InventoryGrid, List<InventoryElement>> Elements = AccessTools.FieldRefAccess<InventoryGrid, List<InventoryElement>>("m_elements");

		private static readonly Dictionary<InventoryElement, ItemState> States = new Dictionary<InventoryElement, ItemState>(RefComparer<InventoryElement>.Instance);

		private static readonly Dictionary<InventoryGrid, GridContext> Grids = new Dictionary<InventoryGrid, GridContext>(RefComparer<InventoryGrid>.Instance);

		private static readonly Dictionary<ItemData, PositionRecord> LastPositions = new Dictionary<ItemData, PositionRecord>(RefComparer<ItemData>.Instance);

		private static readonly Dictionary<ItemData, ItemState> ItemStates = new Dictionary<ItemData, ItemState>(RefComparer<ItemData>.Instance);

		private static readonly List<ItemState> Active = new List<ItemState>();

		private static readonly HashSet<ItemState> QueuedStates = new HashSet<ItemState>();

		private static readonly List<ItemData> DeadItems = new List<ItemData>();

		internal static void BindGrid(InventoryGrid grid, Inventory inventory)
		{
			if ((Object)(object)grid == (Object)null)
			{
				return;
			}
			GridContext orCreateContext = GetOrCreateContext(grid);
			if (orCreateContext.Inventory == inventory)
			{
				return;
			}
			if (orCreateContext.Inventory != null && orCreateContext.ChangedHandler != null)
			{
				Inventory inventory2 = orCreateContext.Inventory;
				inventory2.m_onChanged = (Action)Delegate.Remove(inventory2.m_onChanged, orCreateContext.ChangedHandler);
			}
			orCreateContext.Inventory = inventory;
			orCreateContext.Dirty = true;
			if (inventory != null)
			{
				orCreateContext.ChangedHandler = delegate
				{
					MarkDirty(grid);
				};
				inventory.m_onChanged = (Action)Delegate.Combine(inventory.m_onChanged, orCreateContext.ChangedHandler);
			}
			else
			{
				orCreateContext.ChangedHandler = null;
			}
		}

		internal static void RegisterElement(InventoryElement element)
		{
			if ((Object)(object)element == (Object)null || States.ContainsKey(element))
			{
				return;
			}
			InventoryGrid componentInParent = ((Component)element).GetComponentInParent<InventoryGrid>();
			if (!((Object)(object)componentInParent == (Object)null))
			{
				GridContext orCreateContext = GetOrCreateContext(componentInParent);
				ItemState itemState = CreateState(componentInParent, element);
				itemState.Context = orCreateContext;
				itemState.ContextIndex = orCreateContext.States.Count;
				States.Add(element, itemState);
				orCreateContext.States.Add(itemState);
				orCreateContext.Dirty = true;
				SlotAnimationSystem.RegisterElement(element, componentInParent);
				SmoothUIElementLifecycle smoothUIElementLifecycle = ((Component)element).GetComponent<SmoothUIElementLifecycle>();
				if ((Object)(object)smoothUIElementLifecycle == (Object)null)
				{
					smoothUIElementLifecycle = ((Component)element).gameObject.AddComponent<SmoothUIElementLifecycle>();
				}
				smoothUIElementLifecycle.Bind(element);
			}
		}

		private static GridContext GetOrCreateContext(InventoryGrid grid)
		{
			if (Grids.TryGetValue(grid, out var value))
			{
				return value;
			}
			value = new GridContext
			{
				Grid = grid
			};
			Grids.Add(grid, value);
			SmoothUIGridLifecycle smoothUIGridLifecycle = ((Component)grid).GetComponent<SmoothUIGridLifecycle>();
			if ((Object)(object)smoothUIGridLifecycle == (Object)null)
			{
				smoothUIGridLifecycle = ((Component)grid).gameObject.AddComponent<SmoothUIGridLifecycle>();
			}
			smoothUIGridLifecycle.Bind(grid);
			return value;
		}

		private static void MarkDirty(InventoryGrid grid)
		{
			if ((Object)(object)grid != (Object)null && Grids.TryGetValue(grid, out var value))
			{
				value.Dirty = true;
			}
		}

		internal static void RestoreGrid(InventoryGrid grid)
		{
			if ((Object)(object)grid == (Object)null || Active.Count == 0)
			{
				return;
			}
			for (int i = 0; i < Active.Count; i++)
			{
				ItemState itemState = Active[i];
				if ((Object)(object)itemState.Grid == (Object)(object)grid)
				{
					RestoreState(itemState);
				}
			}
		}

		internal static void CaptureGrid(InventoryGrid grid)
		{
			if ((Object)(object)grid == (Object)null || !Grids.TryGetValue(grid, out var value))
			{
				return;
			}
			if (value.Dirty)
			{
				RefreshGrid(value);
			}
			if (Active.Count == 0)
			{
				return;
			}
			for (int i = 0; i < Active.Count; i++)
			{
				ItemState itemState = Active[i];
				if ((Object)(object)itemState.Grid == (Object)(object)grid && (Object)(object)itemState.Element != (Object)null)
				{
					CaptureBaselines(itemState);
				}
			}
		}

		private static void RefreshGrid(GridContext context)
		{
			context.Dirty = false;
			Inventory val = context.Inventory ?? context.Grid.GetInventory();
			if (val == null)
			{
				return;
			}
			List<InventoryElement> list;
			try
			{
				list = Elements.Invoke(context.Grid);
			}
			catch
			{
				return;
			}
			if (list == null)
			{
				return;
			}
			int num = ++context.Generation;
			int num2 = Mathf.Max(1, val.GetWidth());
			float unscaledTime = Time.unscaledTime;
			List<ItemData> allItems = val.GetAllItems();
			for (int i = 0; i < allItems.Count; i++)
			{
				ItemData val2 = allItems[i];
				if (val2 == null)
				{
					continue;
				}
				int num3 = val2.m_gridPos.y * num2 + val2.m_gridPos.x;
				if (num3 < 0 || num3 >= list.Count)
				{
					continue;
				}
				InventoryElement val3 = list[num3];
				if ((Object)(object)val3 == (Object)null)
				{
					continue;
				}
				if (!States.TryGetValue(val3, out var value))
				{
					RegisterElement(val3);
					if (!States.TryGetValue(val3, out value))
					{
						continue;
					}
				}
				value.Generation = num;
				value.Grid = context.Grid;
				UpdateItemState(value, val3, val2, unscaledTime);
			}
			for (int num4 = context.Occupied.Count - 1; num4 >= 0; num4--)
			{
				ItemState itemState = context.Occupied[num4];
				if (itemState == null || (Object)(object)itemState.Element == (Object)null || itemState.Generation != num)
				{
					ClearItemState(itemState);
				}
			}
			PruneOldPositions(unscaledTime);
		}

		private static void UpdateItemState(ItemState state, InventoryElement element, ItemData item, float now)
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_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_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			int stack = item.m_stack;
			if (item != state.Item)
			{
				QueuedStates.Remove(state);
				state.StackDirection = 0;
				state.Queued = false;
				ItemData item2 = state.Item;
				if (item2 != null && ItemStates.TryGetValue(item2, out var value) && value == state)
				{
					ItemStates.Remove(item2);
				}
				state.Item = item;
				ItemStates[item] = state;
				EnsureOccupied(state);
				state.Stack = stack;
				state.PulseTimer = 999f;
				state.EquipTimer = 999f;
				state.QueueTimer = 999f;
				state.Equipped = item.m_equipped;
				state.Queued = (Object)(object)element.m_queued != (Object)null && ((Behaviour)element.m_queued).enabled;
				if (state.Queued)
				{
					QueuedStates.Add(state);
				}
				state.HasStatusSnapshot = true;
				Vector3 primaryWorld = GetPrimaryWorld(state);
				if (LastPositions.TryGetValue(item, out var value2) && now - value2.LastSeen < 300f)
				{
					Vector3 val = value2.World - primaryWorld;
					if (((Vector3)(ref val)).sqrMagnitude > 1f)
					{
						state.MoveFromWorld = value2.World;
						state.MoveTimer = 0f;
						state.AppearTimer = 999f;
						goto IL_0160;
					}
				}
				state.MoveTimer = 999f;
				state.AppearTimer = 0f;
				goto IL_0160;
			}
			if (stack != state.Stack)
			{
				state.StackDirection = ((stack > state.Stack) ? 1 : (-1));
				state.Stack = stack;
				state.PulseTimer = 0f;
				Activate(state);
			}
			bool equipped = item.m_equipped;
			if (state.HasStatusSnapshot && equipped != state.Equipped)
			{
				state.Equipped = equipped;
				state.EquipTimer = 0f;
				Activate(state);
			}
			bool flag = (Object)(object)element.m_queued != (Object)null && ((Behaviour)element.m_queued).enabled;
			if (state.HasStatusSnapshot && flag != state.Queued)
			{
				state.Queued = flag;
				state.QueueTimer = 0f;
				Activate(state);
				if (flag)
				{
					QueuedStates.Add(state);
				}
				else
				{
					QueuedStates.Remove(state);
				}
			}
			state.HasStatusSnapshot = true;
			goto IL_0240;
			IL_0160:
			Activate(state);
			goto IL_0240;
			IL_0240:
			if (!LastPositions.TryGetValue(item, out var value3))
			{
				value3 = new PositionRecord();
				LastPositions.Add(item, value3);
			}
			value3.World = GetPrimaryWorld(state);
			value3.LastSeen = now;
		}

		private static void EnsureOccupied(ItemState state)
		{
			if (state.OccupiedIndex < 0 && state.Context != null)
			{
				state.OccupiedIndex = state.Context.Occupied.Count;
				state.Context.Occupied.Add(state);
			}
		}

		private static void RemoveOccupied(ItemState state)
		{
			GridContext gridContext = state?.Context;
			if (gridContext == null || state.OccupiedIndex < 0)
			{
				return;
			}
			int occupiedIndex = state.OccupiedIndex;
			int num = gridContext.Occupied.Count - 1;
			if (occupiedIndex >= 0 && occupiedIndex <= num)
			{
				if (occupiedIndex != num)
				{
					ItemState itemState = gridContext.Occupied[num];
					gridContext.Occupied[occupiedIndex] = itemState;
					itemState.OccupiedIndex = occupiedIndex;
				}
				gridContext.Occupied.RemoveAt(num);
			}
			state.OccupiedIndex = -1;
		}

		private static void ClearItemState(ItemState state)
		{
			if (state != null)
			{
				RestoreState(state);
				Deactivate(state);
				QueuedStates.Remove(state);
				if (state.Item != null && ItemStates.TryGetValue(state.Item, out var value) && value == state)
				{
					ItemStates.Remove(state.Item);
				}
				state.Item = null;
				state.Stack = 0;
				state.StackDirection = 0;
				state.Equipped = false;
				state.Queued = false;
				state.HasStatusSnapshot = false;
				state.AppearTimer = 999f;
				state.MoveTimer = 999f;
				state.PulseTimer = 999f;
				state.EquipTimer = 999f;
				state.QueueTimer = 999f;
				RemoveOccupied(state);
			}
		}

		internal static void UnregisterElement(InventoryElement element)
		{
			if (element != null && States.TryGetValue(element, out var value))
			{
				RemoveState(value);
			}
		}

		private static void RemoveState(ItemState state)
		{
			if (state == null)
			{
				return;
			}
			ClearItemState(state);
			if (state.Element != null)
			{
				SlotAnimationSystem.UnregisterElement(state.Element);
				States.Remove(state.Element);
			}
			GridContext context = state.Context;
			if (context != null && state.ContextIndex >= 0)
			{
				int contextIndex = state.ContextIndex;
				int num = context.States.Count - 1;
				if (contextIndex >= 0 && contextIndex <= num)
				{
					if (contextIndex != num)
					{
						ItemState itemState = context.States[num];
						context.States[contextIndex] = itemState;
						itemState.ContextIndex = contextIndex;
					}
					context.States.RemoveAt(num);
				}
			}
			state.Context = null;
			state.ContextIndex = -1;
			state.Element = null;
		}

		private static ItemState CreateState(InventoryGrid grid, InventoryElement element)
		{
			ItemState obj = new ItemState
			{
				Grid = grid,
				Element = element
			};
			AddPart(obj, ((Object)(object)element.m_icon != (Object)null) ? ((Component)element.m_icon).transform : null);
			AddPart(obj, ((Object)(object)element.m_amount != (Object)null) ? element.m_amount.transform : null);
			AddPart(obj, ((Object)(object)element.m_quality != (Object)null) ? element.m_quality.transform : null);
			AddPart(obj, ((Object)(object)element.m_equiped != (Object)null) ? ((Component)element.m_equiped).transform : null);
			AddPart(obj, ((Object)(object)element.m_queued != (Object)null) ? ((Component)element.m_queued).transform : null);
			AddPart(obj, ((Object)(object)element.m_noteleport != (Object)null) ? ((Component)element.m_noteleport).transform : null);
			AddPart(obj, ((Object)(object)element.m_food != (Object)null) ? ((Component)element.m_food).transform : null);
			AddPart(obj, ((Object)(object)element.m_durability != (Object)null) ? ((Component)element.m_durability).transform : null);
			CaptureBaselines(obj);
			return obj;
		}

		private static void AddPart(ItemState state, Transform transform)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)transform == (Object)null))
			{
				state.Parts.Add(new PartState
				{
					Transform = transform,
					BasePosition = transform.localPosition,
					BaseScale = transform.localScale,
					BaseRotation = transform.localRotation
				});
			}
		}

		private static void CaptureBaselines(ItemState state)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < state.Parts.Count; i++)
			{
				PartState partState = state.Parts[i];
				if (!((Object)(object)partState.Transform == (Object)null))
				{
					partState.BasePosition = partState.Transform.localPosition;
					partState.BaseScale = partState.Transform.localScale;
					partState.BaseRotation = partState.Transform.localRotation;
					partState.Applied = false;
					partState.AppliedPosition = Vector3.zero;
					partState.AppliedScale = 1f;
					partState.AppliedRotation = 0f;
				}
			}
		}

		internal static void Tick()
		{
			//IL_0289: Unknown result type (might be due to invalid IL or missing references)
			//IL_028e: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: 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_02ea: Unknown result type (might be due to invalid IL or missing references)
			if (!WiresSmoothUIPlugin.ItemAnimations.Value)
			{
				RestoreActive();
			}
			else
			{
				if (Active.Count == 0)
				{
					return;
				}
				float dt = WiresSmoothUIPlugin.Dt;
				for (int num = Active.Count - 1; num >= 0; num--)
				{
					ItemState itemState = Active[num];
					InventoryElement element = itemState.Element;
					if ((Object)(object)element == (Object)null || itemState.Item == null || (Object)(object)element.m_icon == (Object)null || !((Behaviour)element.m_icon).enabled || !((Component)element).gameObject.activeInHierarchy)
					{
						RestoreState(itemState);
						DeactivateAt(num);
					}
					else
					{
						itemState.AppearTimer += dt;
						itemState.MoveTimer += dt;
						itemState.PulseTimer += dt;
						itemState.EquipTimer += dt;
						itemState.QueueTimer += dt;
						float num2 = 1f;
						float num3 = 1f;
						float equipMarkerScale = 1f;
						float queueMarkerScale = 1f;
						float num4 = 0f;
						float num5 = Mathf.Max(0.01f, WiresSmoothUIPlugin.ItemAppearDuration.Value);
						if (itemState.AppearTimer < num5)
						{
							float t = itemState.AppearTimer / num5;
							num2 *= WiresSmoothUIPlugin.PopScale(t, 0.78f);
						}
						if (itemState.PulseTimer < 0.16f)
						{
							float num6 = Mathf.Sin(Mathf.Clamp01(itemState.PulseTimer / 0.16f) * (float)Math.PI);
							num2 *= 1f + (Mathf.Max(1f, WiresSmoothUIPlugin.StackPulseScale.Value) - 1f) * num6;
							num3 = ((itemState.StackDirection >= 0) ? (num3 * (1f + 0.12f * num6)) : (num3 * (1f - 0.08f * num6)));
						}
						if (itemState.EquipTimer < 0.18f)
						{
							float num7 = Mathf.Clamp01(itemState.EquipTimer / 0.18f);
							float num8 = Mathf.Sin(num7 * (float)Math.PI);
							num2 *= 1f + 0.035f * num8;
							num4 += (itemState.Equipped ? (-2f) : 2f) * num8;
							if (itemState.Equipped)
							{
								equipMarkerScale = WiresSmoothUIPlugin.PopScale(num7, 0.65f);
							}
						}
						if (itemState.QueueTimer < 0.18f)
						{
							float num9 = Mathf.Clamp01(itemState.QueueTimer / 0.18f);
							float num10 = Mathf.Sin(num9 * (float)Math.PI);
							num2 *= 1f + 0.02f * num10;
							if (itemState.Queued)
							{
								queueMarkerScale = WiresSmoothUIPlugin.PopScale(num9, 0.68f);
							}
						}
						Vector3 worldMove = Vector3.zero;
						float num11 = Mathf.Max(0.01f, WiresSmoothUIPlugin.ItemMoveDuration.Value);
						if (itemState.MoveTimer < num11)
						{
							float num12 = Mathf.Clamp01(itemState.MoveTimer / num11);
							float num13 = WiresSmoothUIPlugin.EaseOutCubic(num12);
							Vector3 primaryWorld = GetPrimaryWorld(itemState);
							worldMove = Vector3.LerpUnclamped(itemState.MoveFromWorld - primaryWorld, Vector3.zero, num13);
							if (num12 > 0.55f)
							{
								float num14 = (num12 - 0.55f) / 0.45f;
								num2 *= 1f + Mathf.Sin(num14 * (float)Math.PI) * 0.04f;
							}
						}
						ApplyState(itemState, num2, num3, equipMarkerScale, queueMarkerScale, num4, worldMove);
						if (itemState.AppearTimer >= num5 && itemState.MoveTimer >= num11 && itemState.PulseTimer >= 0.16f && itemState.EquipTimer >= 0.18f && itemState.QueueTimer >= 0.18f)
						{
							RestoreState(itemState);
							DeactivateAt(num);
						}
					}
				}
			}
		}

		private static void ApplyState(ItemState state, float scale, float amountScale, float equipMarkerScale, float queueMarkerScale, float iconRotation, Vector3 worldMove)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: 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_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0168: Unknown result type (might be due to invalid IL or missing references)
			//IL_0174: 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_0187: 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_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)
			for (int i = 0; i < state.Parts.Count; i++)
			{
				PartState partState = state.Parts[i];
				Transform transform = partState.Transform;
				if (!((Object)(object)transform == (Object)null))
				{
					Vector3 val = (((Object)(object)transform.parent != (Object)null) ? transform.parent.InverseTransformVector(worldMove) : worldMove);
					bool num = (Object)(object)state.Element != (Object)null && (Object)(object)state.Element.m_icon != (Object)null && (Object)(object)transform == (Object)(object)((Component)state.Element.m_icon).transform;
					bool flag = (Object)(object)state.Element != (Object)null && (Object)(object)state.Element.m_amount != (Object)null && (Object)(object)transform == (Object)(object)state.Element.m_amount.transform;
					bool flag2 = (Object)(object)state.Element != (Object)null && (Object)(object)state.Element.m_equiped != (Object)null && (Object)(object)transform == (Object)(object)((Component)state.Element.m_equiped).transform;
					bool num2 = (Object)(object)state.Element != (Object)null && (Object)(object)state.Element.m_queued != (Object)null && (Object)(object)transform == (Object)(object)((Component)state.Element.m_queued).transform;
					float num3 = scale;
					if (flag)
					{
						num3 *= amountScale;
					}
					if (flag2)
					{
						num3 *= equipMarkerScale;
					}
					if (num2)
					{
						num3 *= queueMarkerScale;
					}
					float num4 = (num ? iconRotation : 0f);
					transform.localPosition = partState.BasePosition + val;
					transform.localScale = partState.BaseScale * num3;
					transform.localRotation = partState.BaseRotation * Quaternion.Euler(0f, 0f, num4);
					partState.AppliedPosition = val;
					partState.AppliedScale = num3;
					partState.AppliedRotation = num4;
					partState.Applied = true;
				}
			}
		}

		private static Vector3 GetPrimaryWorld(ItemState state)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)state.Element != (Object)null && (Object)(object)state.Element.m_icon != (Object)null)
			{
				return ((Component)state.Element.m_icon).transform.position;
			}
			if (!((Object)(object)state.Element != (Object)null))
			{
				return Vector3.zero;
			}
			return ((Component)state.Element).transform.position;
		}

		private static void RestoreState(ItemState state)
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: 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_00a9: 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_009b: 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_00b9: 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_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0100: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: 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)
			if (state == null)
			{
				return;
			}
			for (int i = 0; i < state.Parts.Count; i++)
			{
				PartState partState = state.Parts[i];
				Transform transform = partState.Transform;
				if (!((Object)(object)transform == (Object)null) && partState.Applied)
				{
					Vector3 val = partState.BasePosition + partState.AppliedPosition;
					Vector3 val2 = partState.BaseScale * partState.AppliedScale;
					Quaternion val3 = partState.BaseRotation * Quaternion.Euler(0f, 0f, partState.AppliedRotation);
					Vector3 val4 = transform.localPosition - val;
					if (((Vector3)(ref val4)).sqrMagnitude < 0.0009f)
					{
						transform.localPosition = partState.BasePosition;
					}
					else
					{
						partState.BasePosition = transform.localPosition;
					}
					val4 = transform.localScale - val2;
					if (((Vector3)(ref val4)).sqrMagnitude < 0.0009f)
					{
						transform.localScale = partState.BaseScale;
					}
					else
					{
						partState.BaseScale = transform.localScale;
					}
					if (Quaternion.Angle(transform.localRotation, val3) < 0.05f)
					{
						transform.localRotation = partState.BaseRotation;
					}
					else
					{
						partState.BaseRotation = transform.localRotation;
					}
					partState.Applied = false;
					partState.AppliedPosition = Vector3.zero;
					partState.AppliedScale = 1f;
					partState.AppliedRotation = 0f;
				}
			}
		}

		private static void Activate(ItemState state)
		{
			if (state.ActiveIndex < 0)
			{
				state.ActiveIndex = Active.Count;
				Active.Add(state);
			}
		}

		private static void Deactivate(ItemState state)
		{
			if (state.ActiveIndex >= 0)
			{
				DeactivateAt(state.ActiveIndex);
			}
		}

		private static void DeactivateAt(int index)
		{
			int num = Active.Count - 1;
			ItemState itemState = Active[index];
			if (index != num)
			{
				ItemState itemState2 = Active[num];
				Active[index] = itemState2;
				itemState2.ActiveIndex = index;
			}
			Active.RemoveAt(num);
			itemState.ActiveIndex = -1;
		}

		private static void RestoreActive()
		{
			for (int num = Active.Count - 1; num >= 0; num--)
			{
				RestoreState(Active[num]);
				DeactivateAt(num);
			}
		}

		internal static void NotifyEquipment(ItemData item, bool equipped)
		{
			if (item != null && ItemStates.TryGetValue(item, out var value))
			{
				value.Equipped = equipped;
				value.HasStatusSnapshot = true;
				value.EquipTimer = 0f;
				Activate(value);
			}
		}

		internal static void NotifyQueue(ItemData item, bool queued)
		{
			if (item != null && ItemStates.TryGetValue(item, out var value) && (value.Queued != queued || !value.HasStatusSnapshot))
			{
				value.Queued = queued;
				value.HasStatusSnapshot = true;
				value.QueueTimer = 0f;
				Activate(value);
				if (queued)
				{
					QueuedStates.Add(value);
				}
				else
				{
					QueuedStates.Remove(value);
				}
			}
		}

		internal static void NotifyAllQueuesCleared()
		{
			foreach (ItemState queuedState in QueuedStates)
			{
				if (queuedState != null)
				{
					queuedState.Queued = false;
					queuedState.HasStatusSnapshot = true;
					queuedState.QueueTimer = 0f;
					Activate(queuedState);
				}
			}
			QueuedStates.Clear();
		}

		private static void PruneOldPositions(float now)
		{
			if (LastPositions.Count < 512)
			{
				return;
			}
			DeadItems.Clear();
			foreach (KeyValuePair<ItemData, PositionRecord> lastPosition in LastPositions)
			{
				if (lastPosition.Key == null || now - lastPosition.Value.LastSeen > 300f)
				{
					DeadItems.Add(lastPosition.Key);
				}
			}
			for (int i = 0; i < DeadItems.Count; i++)
			{
				LastPositions.Remove(DeadItems[i]);
			}
		}

		internal static void UnregisterGrid(InventoryGrid grid)
		{
			if (grid != null && Grids.TryGetValue(grid, out var value))
			{
				if (value.Inventory != null && value.ChangedHandler != null)
				{
					Inventory inventory = value.Inventory;
					inventory.m_onChanged = (Action)Delegate.Remove(inventory.m_onChanged, value.ChangedHandler);
				}
				for (int num = value.States.Count - 1; num >= 0; num--)
				{
					RemoveState(value.States[num]);
				}
				Grids.Remove(grid);
			}
		}

		internal static void RestoreAll()
		{
			RestoreActive();
		}

		internal static void Shutdown()
		{
			RestoreActive();
			foreach (KeyValuePair<InventoryGrid, GridContext> grid in Grids)
			{
				GridContext value = grid.Value;
				if (value.Inventory != null && value.ChangedHandler != null)
				{
					Inventory inventory = value.Inventory;
					inventory.m_onChanged = (Action)Delegate.Remove(inventory.m_onChanged, value.ChangedHandler);
				}
				for (int num = value.States.Count - 1; num >= 0; num--)
				{
					RemoveState(value.States[num]);
				}
			}
			States.Clear();
			Grids.Clear();
			ItemStates.Clear();
			QueuedStates.Clear();
			LastPositions.Clear();
			DeadItems.Clear();
		}
	}
	internal sealed class SmoothUIElementLifecycle : MonoBehaviour
	{
		private InventoryElement _element;

		internal void Bind(InventoryElement element)
		{
			_element = element;
		}

		private void OnDestroy()
		{
			ItemAnimationSystem.UnregisterElement(_element);
		}
	}
	internal sealed class SmoothUIGridLifecycle : MonoBehaviour
	{
		private InventoryGrid _grid;

		internal void Bind(InventoryGrid grid)
		{
			_grid = grid;
		}

		private void OnDestroy()
		{
			ItemAnimationSystem.UnregisterGrid(_grid);
		}
	}
	[HarmonyPatch(typeof(InventoryGrid), "UpdateInventory")]
	internal static class SmoothUIInventoryGridBindPatch
	{
		[HarmonyPrefix]
		private static void Prefix(InventoryGrid __instance, Inventory inventory)
		{
			ItemAnimationSystem.BindGrid(__instance, inventory);
		}
	}
	[HarmonyPatch(typeof(Humanoid), "EquipItem", new Type[]
	{
		typeof(ItemData),
		typeof(bool)
	})]
	internal static class SmoothUIEquipItemPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Humanoid __instance, ItemData item, bool __result)
		{
			if (__result && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				ItemAnimationSystem.NotifyEquipment(item, equipped: true);
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "UnequipItem", new Type[]
	{
		typeof(ItemData),
		typeof(bool)
	})]
	internal static class SmoothUIUnequipItemPatch
	{
		[HarmonyPrefix]
		private static void Prefix(ItemData item, ref bool __state)
		{
			__state = item?.m_equipped ?? false;
		}

		[HarmonyPostfix]
		private static void Postfix(Humanoid __instance, ItemData item, bool __state)
		{
			if (__state && item != null && !item.m_equipped && (Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				ItemAnimationSystem.NotifyEquipment(item, equipped: false);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "QueueEquipAction")]
	internal static class SmoothUIQueueEquipPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Player __instance, ItemData item)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				bool queued = __instance.IsEquipActionQueued(item);
				ItemAnimationSystem.NotifyQueue(item, queued);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "QueueUnequipAction")]
	internal static class SmoothUIQueueUnequipPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Player __instance, ItemData item)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				bool queued = __instance.IsEquipActionQueued(item);
				ItemAnimationSystem.NotifyQueue(item, queued);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "RemoveEquipAction")]
	internal static class SmoothUIRemoveEquipActionPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Player __instance, ItemData item)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				bool queued = __instance.IsEquipActionQueued(item);
				ItemAnimationSystem.NotifyQueue(item, queued);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "ClearActionQueue")]
	internal static class SmoothUIClearActionQueuePatch
	{
		[HarmonyPostfix]
		private static void Postfix(Player __instance)
		{
			if ((Object)(object)__instance == (Object)(object)Player.m_localPlayer)
			{
				ItemAnimationSystem.NotifyAllQueuesCleared();
			}
		}
	}
	[HarmonyPatch(typeof(InventoryElement), "Initialize")]
	internal static class SmoothUIInventoryElementInitializePatch
	{
		[HarmonyPostfix]
		private static void Postfix(InventoryElement __instance)
		{
			ItemAnimationSystem.RegisterElement(__instance);
		}
	}
	internal static class MapPinAnimationSystem
	{
		internal struct ToggleState
		{
			internal PinData Pin;

			internal bool Checked;

			internal long OwnerId;
		}

		private static readonly List<PinData> Pending = new List<PinData>(8);

		private static readonly MethodInfo ClosestPinToCursor = AccessTools.Method(typeof(Minimap), "GetClosestPinToCursor", (Type[])null, (Type[])null);

		private const float Strength = 1f;

		private static bool Enabled
		{
			get
			{
				if (WiresSmoothUIPlugin.Enabled.Value)
				{
					return WiresSmoothUIPlugin.MapPinAnimations.Value;
				}
				return false;
			}
		}

		internal static void OnPinAdded(Minimap minimap, PinData pin, bool save, long ownerId)
		{
			if (Enabled && !((Object)(object)minimap == (Object)null) && pin != null && !pin.m_animate && (!save || Minimap.IsOpen()) && (ownerId == 0L || Minimap.IsOpen()) && !Pending.Contains(pin))
			{
				Pending.Add(pin);
			}
		}

		internal static void OnPinRemoved(PinData pin)
		{
			if (pin != null)
			{
				Pending.Remove(pin);
			}
		}

		internal static void ProcessPending()
		{
			if (!Enabled || Pending.Count == 0)
			{
				return;
			}
			float peakScale = Mathf.Max(1f, WiresSmoothUIPlugin.MapPinPopScale.Value);
			float duration = Mathf.Max(0.05f, WiresSmoothUIPlugin.MapPinPopDuration.Value);
			for (int num = Pending.Count - 1; num >= 0; num--)
			{
				PinData val = Pending[num];
				if (val == null)
				{
					Pending.RemoveAt(num);
				}
				else if (val.m_animate)
				{
					Pending.RemoveAt(num);
				}
				else if (!((Object)(object)val.m_uiElement == (Object)null) && ((Component)val.m_uiElement).gameObject.activeInHierarchy)
				{
					MicroMotionSystem.Pop((Transform)(object)val.m_uiElement, 0.72f, peakScale, duration);
					Pending.RemoveAt(num);
				}
			}
		}

		internal static ToggleState CaptureToggle(Minimap minimap)
		{
			ToggleState result = default(ToggleState);
			if (!Enabled || (Object)(object)minimap == (Object)null || ClosestPinToCursor == null)
			{
				return result;
			}
			try
			{
				object? obj = ClosestPinToCursor.Invoke(minimap, null);
				result.Pin = (PinData)((obj is PinData) ? obj : null);
				if (result.Pin != null)
				{
					result.Checked = result.Pin.m_checked;
					result.OwnerId = result.Pin.m_ownerID;
				}
			}
			catch
			{
				result.Pin = null;
			}
			return result;
		}

		internal static void FinishToggle(ToggleState state)
		{
			if (Enabled && state.Pin != null && !((Object)(object)state.Pin.m_uiElement == (Object)null) && (state.Checked != state.Pin.m_checked || state.OwnerId != state.Pin.m_ownerID))
			{
				MicroMotionSystem.Punch((Transform)(object)state.Pin.m_uiElement, 0.92f, 1.09f, 0.18f);
			}
		}

		internal static void AnimateIconFilter(Minimap minimap, PinType type)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			if (Enabled && !((Object)(object)minimap == (Object)null) && Minimap.IsOpen())
			{
				Image selectionImage = GetSelectionImage(minimap, type);
				Transform val = (((Object)(object)selectionImage != (Object)null && (Object)(object)((Component)selectionImage).transform.parent != (Object)null) ? ((Component)selectionImage).transform.parent : ((selectionImage != null) ? ((Component)selectionImage).transform : null));
				if ((Object)(object)val != (Object)null)
				{
					MicroMotionSystem.Punch(val, 0.95f, 1.055f, 0.16f);
				}
			}
		}

		internal static void AnimateNameInput(Minimap minimap)
		{
			if (Enabled && !((Object)(object)minimap?.m_nameInput == (Object)null) && ((Component)minimap.m_nameInput).gameObject.activeInHierarchy)
			{
				MicroMotionSystem.Pop(((Component)minimap.m_nameInput).transform, 0.92f, 1.05f, 0.18f);
			}
		}

		private static Image GetSelectionImage(Minimap minimap, PinType type)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Expected I4, but got Unknown
			return (Image)((int)type switch
			{
				0 => minimap.m_selectedIcon0, 
				1 => minimap.m_selectedIcon1, 
				2 => minimap.m_selectedIcon2, 
				3 => minimap.m_selectedIcon3, 
				6 => minimap.m_selectedIcon4, 
				4 => minimap.m_selectedIconDeath, 
				9 => minimap.m_selectedIconBoss, 
				12 => minimap.m_selectedIconPing, 
				_ => null, 
			});
		}

		internal static void Shutdown()
		{
			Pending.Clear();
		}
	}
	[HarmonyPatch(typeof(Minimap), "AddPin")]
	internal static class SmoothUIMapPinAddPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Minimap __instance, bool save, long ownerID, PinData __result)
		{
			MapPinAnimationSystem.OnPinAdded(__instance, __result, save, ownerID);
		}
	}
	[HarmonyPatch(typeof(Minimap), "RemovePin", new Type[] { typeof(PinData) })]
	internal static class SmoothUIMapPinRemovePatch
	{
		[HarmonyPrefix]
		private static void Prefix(PinData pin)
		{
			MapPinAnimationSystem.OnPinRemoved(pin);
		}
	}
	[HarmonyPatch(typeof(Minimap), "UpdatePins")]
	internal static class SmoothUIMapPinUpdatePatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			MapPinAnimationSystem.ProcessPending();
		}
	}
	[HarmonyPatch(typeof(Minimap), "OnMapLeftClick")]
	internal static class SmoothUIMapPinTogglePatch
	{
		[HarmonyPrefix]
		private static void Prefix(Minimap __instance, out MapPinAnimationSystem.ToggleState __state)
		{
			__state = MapPinAnimationSystem.CaptureToggle(__instance);
		}

		[HarmonyPostfix]
		private static void Postfix(MapPinAnimationSystem.ToggleState __state)
		{
			MapPinAnimationSystem.FinishToggle(__state);
		}
	}
	[HarmonyPatch(typeof(Minimap), "ToggleIconFilter")]
	internal static class SmoothUIMapFilterIconPatch
	{
		[HarmonyPostfix]
		private static void Postfix(Minimap __instance, PinType type)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			MapPinAnimationSystem.AnimateIconFilter(__instance, type);
		}
	}
	[HarmonyPatch(typeof(Minimap), "Sho