Decompiled source of WearableItemsAPI v0.2.1

Snowlance.WearableItemsAPI.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Snowlance.WearableItemsAPI.NetcodePatcher;
using TMPro;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.Events;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: InternalsVisibleTo("Snowlance.WearableItemsAPI.UI")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")]
[assembly: IgnoresAccessChecksTo("Unity.XR.Management")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")]
[assembly: AssemblyCompany("Snowlance.WearableItemsAPI")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.2.1.0")]
[assembly: AssemblyInformationalVersion("0.2.1+9e9ec92d672299ef84bd34fe1d3328851dbfa177")]
[assembly: AssemblyProduct("WearableItemsAPI")]
[assembly: AssemblyTitle("Snowlance.WearableItemsAPI")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.1.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace WearableItemsAPI
{
	internal static class PlayerControllerBExtensions
	{
		public static bool GrabGrabbableObject(this PlayerControllerB player, GrabbableObject grabbableObject)
		{
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			if (player.twoHanded || player.sinkingValue > 0.73f)
			{
				return false;
			}
			player.currentlyGrabbingObject = grabbableObject;
			if (!GameNetworkManager.Instance.gameHasStarted && !player.currentlyGrabbingObject.itemProperties.canBeGrabbedBeforeGameStart && (Object)(object)StartOfRound.Instance.testRoom == (Object)null)
			{
				return false;
			}
			player.grabInvalidated = false;
			if ((Object)(object)player.currentlyGrabbingObject == (Object)null || player.inSpecialInteractAnimation || player.currentlyGrabbingObject.isHeld || player.currentlyGrabbingObject.isPocketed)
			{
				return false;
			}
			NetworkObject networkObject = ((NetworkBehaviour)player.currentlyGrabbingObject).NetworkObject;
			if ((Object)(object)networkObject == (Object)null || !networkObject.IsSpawned)
			{
				return false;
			}
			player.currentlyGrabbingObject.InteractItem();
			if (!player.currentlyGrabbingObject.grabbable || player.FirstEmptyItemSlot(player.currentlyGrabbingObject) == -1)
			{
				return false;
			}
			player.playerBodyAnimator.SetBool("GrabInvalidated", false);
			player.playerBodyAnimator.SetBool("GrabValidated", false);
			player.playerBodyAnimator.SetBool("cancelHolding", false);
			player.playerBodyAnimator.ResetTrigger("Throw");
			player.SetSpecialGrabAnimationBool(true, (GrabbableObject)null);
			player.isGrabbingObjectAnimation = true;
			((Behaviour)player.cursorIcon).enabled = false;
			((TMP_Text)player.cursorTip).text = "";
			player.twoHanded = player.currentlyGrabbingObject.itemProperties.twoHanded;
			player.carryWeight = Mathf.Clamp(player.carryWeight + (player.currentlyGrabbingObject.itemProperties.weight - 1f), 1f, 10f);
			StartOfRound.Instance.SendChangedWeightEvent();
			if (player.currentlyGrabbingObject.itemProperties.grabAnimationTime > 0f)
			{
				player.grabObjectAnimationTime = player.currentlyGrabbingObject.itemProperties.grabAnimationTime;
			}
			else
			{
				player.grabObjectAnimationTime = 0.4f;
			}
			if (!player.isTestingPlayer)
			{
				player.GrabObjectServerRpc(NetworkObjectReference.op_Implicit(networkObject));
			}
			if (player.grabObjectCoroutine != null)
			{
				((MonoBehaviour)player).StopCoroutine(player.grabObjectCoroutine);
			}
			player.grabObjectCoroutine = ((MonoBehaviour)player).StartCoroutine(player.GrabObject());
			return true;
		}
	}
	public static class PlayerWearables
	{
		private static readonly Dictionary<PlayerControllerB, List<WearableObject>> wearableLookup = new Dictionary<PlayerControllerB, List<WearableObject>>();

		internal static UnityEvent OnWearablesUpdate = new UnityEvent();

		public static List<WearableObject> GetWearables(this PlayerControllerB player)
		{
			if (!wearableLookup.TryGetValue(player, out List<WearableObject> value))
			{
				value = new List<WearableObject>();
				wearableLookup[player] = value;
			}
			return value;
		}

		internal static void AddWearable(this PlayerControllerB player, WearableObject item)
		{
			List<WearableObject> wearables = player.GetWearables();
			wearables.Add(item);
			OnWearablesUpdate.Invoke();
		}

		internal static void RemoveWearable(this PlayerControllerB player, WearableObject item)
		{
			List<WearableObject> wearables = player.GetWearables();
			wearables.Remove(item);
			OnWearablesUpdate.Invoke();
		}
	}
	[BepInPlugin("Snowlance.WearableItemsAPI", "WearableItemsAPI", "0.2.1")]
	internal class Plugin : BaseUnityPlugin
	{
		public static Plugin Instance;

		public static ManualLogSource logger;

		private readonly Harmony harmony = new Harmony("Snowlance.WearableItemsAPI");

		public static PlayerControllerB localPlayer => StartOfRound.Instance.localPlayerController;

		public void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			logger = ((BaseUnityPlugin)Instance).Logger;
			harmony.PatchAll();
			InitializeNetworkBehaviours();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"WearableItemsAPI v0.2.1 has loaded!");
		}

		public static void InitializeNetworkBehaviours()
		{
			Type[] types = Assembly.GetExecutingAssembly().GetTypes();
			Type[] array = types;
			foreach (Type type in array)
			{
				MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
				MethodInfo[] array2 = methods;
				foreach (MethodInfo methodInfo in array2)
				{
					object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false);
					if (customAttributes.Length != 0)
					{
						methodInfo.Invoke(null, null);
					}
				}
			}
			logger.LogDebug((object)"Finished initializing network behaviours");
		}
	}
	[HarmonyPatch]
	internal class TESTING : MonoBehaviour
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(HUDManager), "PingScan_performed")]
		public static void PingScan_performedPostFix()
		{
			try
			{
			}
			catch (Exception ex)
			{
				Plugin.logger.LogError((object)ex);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(HUDManager), "SubmitChat_performed")]
		public static void SubmitChat_performedPrefix(HUDManager __instance)
		{
			try
			{
				string text = __instance.chatTextField.text;
				string[] array = text.Split(" ");
				string text2 = array[0];
				string text3 = text2;
				if (!(text3 == "/wi_transforms"))
				{
					if (text3 == "/wi_transformslocal")
					{
						Transform[] componentsInChildren = ((Component)((Component)Plugin.localPlayer.playerBodyAnimator).gameObject.transform.Find("ScavengerModelArmsOnly")).GetComponentsInChildren<Transform>(true);
						foreach (Transform val in componentsInChildren)
						{
							Plugin.logger.LogDebug((object)((Object)val).name);
						}
					}
				}
				else
				{
					Transform[] componentsInChildren2 = ((Component)((Component)Plugin.localPlayer.playerBodyAnimator).gameObject.transform.Find("spine")).GetComponentsInChildren<Transform>(true);
					foreach (Transform val2 in componentsInChildren2)
					{
						Plugin.logger.LogDebug((object)((Object)val2).name);
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.logger.LogError((object)ex);
			}
		}
	}
	[CreateAssetMenu(menuName = "WearableItemsAPI/WearableItem")]
	public class WearableItem : ScriptableObject
	{
		public enum WearableSlot
		{
			None = -1,
			Head,
			RightArm,
			LeftArm,
			RightLeg,
			LeftLeg,
			Chest,
			Feet,
			RightHip,
			LeftHip,
			LeftShoulder,
			RightShoulder
		}

		[Header("Restrictions")]
		[Tooltip("Prevents this item from being worn with any item sharing the same restrictions.")]
		public List<string> restrictions = new List<string>();

		[Tooltip("Prevents other items from being worn in the same slot.")]
		public bool restrictSlot = false;

		[Header("Positioning (Other Players)")]
		[Tooltip("Body part this item attaches to. Used when no bone transform is specified. This also determines which body part is highlighted in the UI when hovering over the item in the menu.")]
		public WearableSlot slot = WearableSlot.None;

		[Tooltip("Name of the bone transform the item should be attached to. Leave empty to use slots. Type '/wi_transforms' in game chat to log available transforms.")]
		public string boneTransform = "";

		[Tooltip("Positional offset relative to the assigned slot or bone transform.")]
		public Vector3 wornPositionOffset = Vector3.zero;

		[Tooltip("Rotational offset relative to the assigned slot or bone transform.")]
		public Vector3 wornRotationOffset = Vector3.zero;

		[Header("Positioning (Local Player)")]
		[Tooltip("Name of the bone transform the item should be attached to for the player wearing it. Leave empty to use slots or `boneTransform`. Type '/wi_transformslocal' in chat to log available transforms.")]
		public string boneTransformLocal = "";

		[Tooltip("Should local offsets be used for the local player?")]
		public bool useLocalOffsets = false;

		[Tooltip("Positional offset for the local player view.")]
		public Vector3 wornPositionOffsetLocal = Vector3.zero;

		[Tooltip("Rotational offset for the local player view.")]
		public Vector3 wornRotationOffsetLocal = Vector3.zero;

		[Header("Visibility")]
		[Tooltip("Determines if the wearable is visible to other players.")]
		public bool showWearable = true;

		[Tooltip("Determines if the wearable is visible to the local player.")]
		public bool showWearableOnClient = true;

		[Header("UI")]
		[Tooltip("Icon shown in the wearable UI. Leave empty to use the item's default icon.")]
		public Sprite icon = null;

		[Header("Behavior")]
		[Tooltip("Automatically wear this item when used by the player.")]
		public bool wearOnUse = false;
	}
	public class WearableObject : PhysicsProp
	{
		[Tooltip("Information about how the item should be worn, such as its position, rotation, and other wearable-specific settings.")]
		public WearableItem wearableItemProperties = null;

		private ScanNodeProperties? scanNode;

		internal static PlayerControllerB localPlayer => StartOfRound.Instance.localPlayerController;

		public PlayerControllerB? playerWornBy { get; private set; }

		public PlayerControllerB? lastPlayerWornBy { get; private set; }

		public override void Start()
		{
			((GrabbableObject)this).Start();
			scanNode = ((Component)this).gameObject.GetComponentInChildren<ScanNodeProperties>();
		}

		public override void Update()
		{
			((GrabbableObject)this).Update();
			if ((Object)(object)playerWornBy != (Object)null)
			{
				lastPlayerWornBy = playerWornBy;
				if (!playerWornBy.isPlayerControlled && ((NetworkBehaviour)this).IsServer)
				{
					Debug.Log((object)("Player (" + playerWornBy.playerUsername + ") died or disconnected, unwearing item " + ((GrabbableObject)this).itemProperties.itemName));
					UnwearRpc();
				}
			}
		}

		public override void LateUpdate()
		{
			//IL_0032: 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_008c: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)((GrabbableObject)this).parentObject != (Object)null && (Object)(object)playerWornBy != (Object)null)
			{
				((Component)this).transform.rotation = ((GrabbableObject)this).parentObject.rotation;
				((Component)this).transform.Rotate((wearableItemProperties.useLocalOffsets && (Object)(object)localPlayer == (Object)(object)playerWornBy) ? wearableItemProperties.wornRotationOffsetLocal : wearableItemProperties.wornRotationOffset);
				((Component)this).transform.position = ((GrabbableObject)this).parentObject.position;
				Vector3 val = ((wearableItemProperties.useLocalOffsets && (Object)(object)localPlayer == (Object)(object)playerWornBy) ? wearableItemProperties.wornPositionOffsetLocal : wearableItemProperties.wornPositionOffset);
				val = ((GrabbableObject)this).parentObject.rotation * val;
				Transform transform = ((Component)this).transform;
				transform.position += val;
				if ((Object)(object)((GrabbableObject)this).radarIcon != (Object)null)
				{
					((GrabbableObject)this).radarIcon.position = ((Component)this).transform.position;
				}
			}
			else
			{
				((GrabbableObject)this).LateUpdate();
			}
		}

		public override void ItemActivate(bool used, bool buttonDown = true)
		{
			((GrabbableObject)this).ItemActivate(used, buttonDown);
			if (buttonDown && wearableItemProperties.wearOnUse)
			{
				WearItem(((GrabbableObject)this).playerHeldBy);
			}
		}

		public void WearItem()
		{
			if (!((Object)(object)playerWornBy != (Object)null) && CanWear(localPlayer))
			{
				WearRpc(localPlayer.actualClientId);
			}
		}

		public void WearItem(PlayerControllerB player)
		{
			if (!((Object)(object)playerWornBy != (Object)null) && CanWear(player))
			{
				WearRpc(player.actualClientId);
			}
		}

		public void UnWearItem()
		{
			if (!((Object)(object)playerWornBy == (Object)null))
			{
				UnwearRpc();
			}
		}

		public bool CanWear(PlayerControllerB player)
		{
			WearableItem wearableItem = wearableItemProperties;
			foreach (WearableObject wearable in localPlayer.GetWearables())
			{
				WearableItem other = wearable.wearableItemProperties;
				if (((other.restrictSlot || wearableItem.restrictSlot) && other.slot == wearableItem.slot) || wearableItem.restrictions.Any((string r) => other.restrictions.Contains(r)))
				{
					HUDManager.Instance.DisplayTip("Can't wear item", "'" + ((GrabbableObject)wearable).itemProperties.itemName + "' is preventing you from wearing this item", true, false, "LC_Tip1");
					return false;
				}
			}
			return true;
		}

		public virtual void OnWear()
		{
		}

		public virtual void OnUnWear()
		{
		}

		internal Transform GetWearableParentObject()
		{
			Plugin.logger.LogDebug((object)"Getting wearable parent object");
			WearableItem wearableItem = wearableItemProperties;
			Transform transform = ((Component)playerWornBy.playerBodyAnimator).transform;
			if ((Object)(object)localPlayer == (Object)(object)playerWornBy && !string.IsNullOrWhiteSpace(wearableItem.boneTransformLocal))
			{
				Transform obj = transform.Find("ScavengerModelArmsOnly");
				Transform val = ((obj != null) ? obj.Find(wearableItem.boneTransformLocal) : null);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			if (!string.IsNullOrWhiteSpace(wearableItem.boneTransform))
			{
				Transform obj2 = transform.Find("spine");
				Transform val2 = ((obj2 != null) ? obj2.Find(wearableItem.boneTransform) : null);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
			if (wearableItem.slot != WearableItem.WearableSlot.None)
			{
				return playerWornBy.bodyParts[(int)wearableItem.slot];
			}
			return ((Component)playerWornBy).transform;
		}

		[Rpc(/*Could not decode attribute arguments.*/)]
		internal void WearRpc(ulong clientId)
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: 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_0170: 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)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1)
			{
				RpcAttributeParams val = new RpcAttributeParams
				{
					RequireOwnership = false
				};
				RpcParams val3 = default(RpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendRpc(2389438674u, val3, val, (SendTo)6, (RpcDelivery)0);
				BytePacker.WriteValueBitPacked(val2, clientId);
				((NetworkBehaviour)this).__endSendRpc(ref val2, 2389438674u, val3, val, (SendTo)6, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1)
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			ulong clientId2 = clientId;
			if ((Object)(object)playerWornBy != (Object)null)
			{
				Debug.Log((object)"Player already wearing item");
				return;
			}
			PlayerControllerB val4 = StartOfRound.Instance.allPlayerScripts.Where((PlayerControllerB x) => x.actualClientId == clientId2).FirstOrDefault();
			if ((Object)(object)val4 == (Object)null)
			{
				Debug.LogError((object)"Couldn't get player from player client id");
				return;
			}
			Debug.Log((object)(val4.playerUsername + " wearing " + ((GrabbableObject)this).itemProperties.itemName));
			playerWornBy = val4;
			playerWornBy.DiscardHeldObject(false, ((NetworkBehaviour)playerWornBy).NetworkObject, default(Vector3), true);
			if ((Object)(object)localPlayer != (Object)(object)playerWornBy)
			{
				((MonoBehaviour)this).StartCoroutine(DelayWear(playerWornBy));
				return;
			}
			((GrabbableObject)this).parentObject = GetWearableParentObject();
			Plugin.logger.LogDebug((object)("Parent set to " + ((Object)((GrabbableObject)this).parentObject).name));
			((Component)this).gameObject.GetComponent<Collider>().enabled = false;
			bool flag = (((Object)(object)localPlayer == (Object)(object)playerWornBy) ? wearableItemProperties.showWearableOnClient : wearableItemProperties.showWearable);
			((GrabbableObject)this).EnableItemMeshes(flag);
			ScanNodeProperties? obj = scanNode;
			if (obj != null)
			{
				((Component)obj).gameObject.SetActive(false);
			}
			val4.AddWearable(this);
			OnWear();
		}

		private IEnumerator DelayWear(PlayerControllerB player)
		{
			yield return (object)new WaitForSeconds(0.1f);
			((GrabbableObject)this).parentObject = GetWearableParentObject();
			Plugin.logger.LogDebug((object)("Parent set to " + ((Object)((GrabbableObject)this).parentObject).name));
			((Component)this).gameObject.GetComponent<Collider>().enabled = false;
			bool _showWearable = (((Object)(object)localPlayer == (Object)(object)playerWornBy) ? wearableItemProperties.showWearableOnClient : wearableItemProperties.showWearable);
			((GrabbableObject)this).EnableItemMeshes(_showWearable);
			ScanNodeProperties? obj = scanNode;
			if (obj != null)
			{
				((Component)obj).gameObject.SetActive(false);
			}
			player.AddWearable(this);
			OnWear();
		}

		[Rpc(/*Could not decode attribute arguments.*/)]
		internal void UnwearRpc()
		{
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Invalid comparison between Unknown and I4
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Invalid comparison between Unknown and I4
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_015e: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager;
			if (networkManager == null || !networkManager.IsListening)
			{
				return;
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1)
			{
				RpcAttributeParams val = new RpcAttributeParams
				{
					RequireOwnership = false
				};
				RpcParams val3 = default(RpcParams);
				FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendRpc(159952068u, val3, val, (SendTo)6, (RpcDelivery)0);
				((NetworkBehaviour)this).__endSendRpc(ref val2, 159952068u, val3, val, (SendTo)6, (RpcDelivery)0);
			}
			if ((int)((NetworkBehaviour)this).__rpc_exec_stage != 1)
			{
				return;
			}
			((NetworkBehaviour)this).__rpc_exec_stage = (__RpcExecStage)0;
			if (!((Object)(object)playerWornBy == (Object)null))
			{
				PlayerControllerB val4 = playerWornBy;
				((GrabbableObject)this).parentObject = null;
				Transform val5 = (val4.isInElevator ? val4.playersManager.elevatorTransform : val4.playersManager.propsContainer);
				((Component)this).transform.SetParent(val5, true);
				val4.SetItemInElevator(val4.isInHangarShipRoom, val4.isInElevator, (GrabbableObject)(object)this);
				((GrabbableObject)this).EnablePhysics(true);
				((GrabbableObject)this).startFallingPosition = ((Component)this).transform.parent.InverseTransformPoint(((Component)this).transform.position);
				((GrabbableObject)this).fallTime = 0f;
				((GrabbableObject)this).FallToGround(false, false, default(Vector3));
				if ((Object)(object)val4 == (Object)(object)localPlayer)
				{
					localPlayer.GrabGrabbableObject((GrabbableObject)(object)this);
				}
				playerWornBy.RemoveWearable(this);
				((Component)this).GetComponent<Collider>().enabled = true;
				ScanNodeProperties? obj = scanNode;
				if (obj != null)
				{
					((Component)obj).gameObject.SetActive(true);
				}
				((GrabbableObject)this).EnableItemMeshes(true);
				OnUnWear();
				playerWornBy = null;
			}
		}

		protected override void __initializeVariables()
		{
			((PhysicsProp)this).__initializeVariables();
		}

		protected override void __initializeRpcs()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			((NetworkBehaviour)this).__registerRpc(2389438674u, new RpcReceiveHandler(__rpc_handler_2389438674), "WearRpc");
			((NetworkBehaviour)this).__registerRpc(159952068u, new RpcReceiveHandler(__rpc_handler_159952068), "UnwearRpc");
			((PhysicsProp)this).__initializeRpcs();
		}

		private static void __rpc_handler_2389438674(NetworkBehaviour? target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0023: 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_0050: Unknown result type (might be due to invalid IL or missing references)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				ulong clientId = default(ulong);
				ByteUnpacker.ReadValueBitPacked(reader, ref clientId);
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((WearableObject)(object)target).WearRpc(clientId);
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		private static void __rpc_handler_159952068(NetworkBehaviour? target, FastBufferReader reader, __RpcParams rpcParams)
		{
			//IL_0029: 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)
			NetworkManager networkManager = target.NetworkManager;
			if (networkManager != null && networkManager.IsListening)
			{
				target.__rpc_exec_stage = (__RpcExecStage)1;
				((WearableObject)(object)target).UnwearRpc();
				target.__rpc_exec_stage = (__RpcExecStage)0;
			}
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string? __getTypeName()
		{
			return "WearableObject";
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Snowlance.WearableItemsAPI";

		public const string PLUGIN_NAME = "WearableItemsAPI";

		public const string PLUGIN_VERSION = "0.2.1";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace __GEN
{
	internal class NetworkVariableSerializationHelper
	{
		[RuntimeInitializeOnLoadMethod]
		internal static void InitializeSerialization()
		{
		}
	}
}
namespace Snowlance.WearableItemsAPI.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}

Snowlance.WearableItemsAPI.UI.dll

Decompiled 2 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using LethalCompanyInputUtils.Api;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("com.olegknyazev.softmask")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("DunGen")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.ASPP")]
[assembly: IgnoresAccessChecksTo("DunGen.Integration.UnityNav")]
[assembly: IgnoresAccessChecksTo("EasyTextEffects")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.CoreUtils")]
[assembly: IgnoresAccessChecksTo("Unity.XR.Management")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.ConformanceAutomation")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MetaQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.MockRuntime")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.OculusQuestSupport")]
[assembly: IgnoresAccessChecksTo("Unity.XR.OpenXR.Features.RuntimeDebugger")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.SpatialTracking")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: IgnoresAccessChecksTo("UnityEngine.XR.LegacyInputHelpers")]
[assembly: AssemblyCompany("Snowlance.WearableItemsAPI.UI")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("0.2.0.0")]
[assembly: AssemblyInformationalVersion("0.2.0+f06ba30bd8cd4f120c509e9511fc58390495ee08")]
[assembly: AssemblyProduct("WearableItemsAPI.UI")]
[assembly: AssemblyTitle("Snowlance.WearableItemsAPI.UI")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.2.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace WearableItemsAPI.UI
{
	internal class ForceDirection : MonoBehaviour
	{
		private RectTransform rt;

		public float forcedZRotation = 0f;

		private Vector3 rot = Vector3.zero;

		private void Awake()
		{
			rot.z = forcedZRotation;
			rt = ((Component)this).GetComponent<RectTransform>();
		}

		private void Update()
		{
			//IL_0024: 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_003f: Unknown result type (might be due to invalid IL or missing references)
			if (!Application.isPlaying)
			{
				rot.z = forcedZRotation;
			}
			if (((Transform)rt).eulerAngles != rot)
			{
				((Transform)rt).eulerAngles = rot;
			}
		}
	}
	[HarmonyPatch]
	internal static class Patches
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(QuickMenuManager), "OpenQuickMenu")]
		private static bool QuickMenuManager_OpenQuickMenuPrefix()
		{
			try
			{
				if ((Object)(object)WearableUIController.Instance != (Object)null && (Object)(object)WearableUIController.Instance.radial != (Object)null)
				{
					return false;
				}
				return true;
			}
			catch (Exception ex)
			{
				Plugin.logger.LogError((object)ex);
				return true;
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(PlayerControllerB), "CanUseItem")]
		private static bool PlayerControllerB_CanUseItemPrefix()
		{
			try
			{
				if ((Object)(object)WearableUIController.Instance != (Object)null && (Object)(object)WearableUIController.Instance.radial != (Object)null)
				{
					return false;
				}
				return true;
			}
			catch (Exception ex)
			{
				Plugin.logger.LogError((object)ex);
				return true;
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
		private static void PlayerControllerB_ConnectClientToPlayerObjectPostfix()
		{
			try
			{
				WearableUIController.Init();
			}
			catch (Exception ex)
			{
				Plugin.logger.LogError((object)ex);
			}
		}
	}
	[BepInPlugin("Snowlance.WearableItemsAPI.UI", "WearableItemsAPI.UI", "0.2.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class Plugin : BaseUnityPlugin
	{
		public static Plugin Instance;

		public static ManualLogSource logger;

		private readonly Harmony harmony = new Harmony("Snowlance.WearableItemsAPI.UI");

		public static PlayerControllerB localPlayer => StartOfRound.Instance.localPlayerController;

		public void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			logger = ((BaseUnityPlugin)Instance).Logger;
			harmony.PatchAll();
			AssetBundle val = AssetBundle.LoadFromFile(Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "wearable_items_assets"));
			WearableUIController.prefab = val.LoadAsset<GameObject>("Assets/ModAssets/WearableItemsUI.prefab");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"WearableItemsAPI.UI v0.2.0 has loaded!");
		}
	}
	internal class RadialMenu : MonoBehaviour
	{
		private RectTransform rt = null;

		public Transform elementsContainer = null;

		public Text textLabel = null;

		[HideInInspector]
		public List<RadialMenuElement> elements = new List<RadialMenuElement>();

		private float currentAngle = 0f;

		private int index = 0;

		private float angleOffset;

		private int previousActiveIndex = 0;

		private PointerEventData pointer = null;

		private WearableUIController? ui => WearableUIController.Instance;

		private int elementCount => elements.Count;

		public void Rebuild()
		{
			//IL_0083: 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)
			angleOffset = ((elementCount > 0) ? (360f / (float)elementCount) : 0f);
			for (int i = 0; i < elementCount; i++)
			{
				RadialMenuElement radialMenuElement = elements[i];
				if (!((Object)(object)radialMenuElement == (Object)null))
				{
					radialMenuElement.parentRM = this;
					radialMenuElement.assignedIndex = i;
					radialMenuElement.setAllAngles(angleOffset * (float)i, angleOffset);
					RectTransform component = ((Component)radialMenuElement).GetComponent<RectTransform>();
					((Transform)component).rotation = Quaternion.Euler(0f, 0f, 0f - radialMenuElement.angleOffset);
					((Component)radialMenuElement.button).transform.localRotation = Quaternion.Euler(0f, 0f, radialMenuElement.angleOffset);
				}
			}
			previousActiveIndex = Mathf.Clamp(previousActiveIndex, 0, elementCount - 1);
			index = Mathf.Clamp(index, 0, elementCount - 1);
		}

		private void Awake()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			pointer = new PointerEventData(EventSystem.current);
			rt = ((Component)this).GetComponent<RectTransform>();
		}

		private void Update()
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue();
			float num = Mathf.Atan2(val.y - ((Transform)rt).position.y, val.x - ((Transform)rt).position.x) * 57.29578f;
			currentAngle = NormalizeAngle(0f - num + 90f + angleOffset / 2f);
			if (angleOffset == 0f || elementCount <= 0)
			{
				return;
			}
			index = Mathf.Clamp((int)(currentAngle / angleOffset), 0, elementCount - 1);
			if ((Object)(object)elements[index] != (Object)null)
			{
				SelectButton(index);
				if (Mouse.current.leftButton.wasPressedThisFrame)
				{
					ExecuteEvents.Execute<ISubmitHandler>(((Component)elements[index].button).gameObject, (BaseEventData)(object)pointer, ExecuteEvents.submitHandler);
				}
			}
		}

		private void SelectButton(int i)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			if (!elements[i].active)
			{
				elements[i].highlightThisElement(pointer);
				ui?.SetBodyOutline(elements[i].item.wearableItemProperties.slot);
				if (previousActiveIndex != i)
				{
					elements[previousActiveIndex].unHighlightThisElement(pointer);
				}
			}
			previousActiveIndex = i;
		}

		private float NormalizeAngle(float angle)
		{
			angle %= 360f;
			if (angle < 0f)
			{
				angle += 360f;
			}
			return angle;
		}
	}
	internal class RadialMenuElement : MonoBehaviour
	{
		public Button button = null;

		public Image icon = null;

		[HideInInspector]
		public RadialMenu parentRM = null;

		[HideInInspector]
		public string label = null;

		[HideInInspector]
		public WearableObject item = null;

		[HideInInspector]
		public float angleMin;

		[HideInInspector]
		public float angleMax;

		[HideInInspector]
		public float angleOffset;

		[HideInInspector]
		public bool active = false;

		[HideInInspector]
		public int assignedIndex = 0;

		private RectTransform rt = null;

		private void Awake()
		{
			rt = ((Component)this).gameObject.GetComponent<RectTransform>();
		}

		public void setAllAngles(float offset, float baseOffset)
		{
			angleOffset = offset;
			angleMin = offset - baseOffset / 2f;
			angleMax = offset + baseOffset / 2f;
		}

		public void highlightThisElement(PointerEventData p)
		{
			ExecuteEvents.Execute<ISelectHandler>(((Component)button).gameObject, (BaseEventData)(object)p, ExecuteEvents.selectHandler);
			active = true;
			setParentMenuLable(label);
		}

		public void setParentMenuLable(string l)
		{
			if ((Object)(object)parentRM.textLabel != (Object)null)
			{
				parentRM.textLabel.text = l;
			}
		}

		public void unHighlightThisElement(PointerEventData p)
		{
			ExecuteEvents.Execute<IDeselectHandler>(((Component)button).gameObject, (BaseEventData)(object)p, ExecuteEvents.deselectHandler);
			active = false;
		}
	}
	internal class WearableItemsInputs : LcInputActions
	{
		public static WearableItemsInputs Instance = new WearableItemsInputs();

		public string OpenUIKey_BindingDisplayString => InputActionRebindingExtensions.GetBindingDisplayString(OpenUIKey, StartOfRound.Instance.localPlayerUsingController ? 1 : 0, (DisplayStringOptions)0);

		[InputAction(/*Could not decode attribute arguments.*/)]
		public InputAction OpenUIKey { get; set; } = null;
	}
	internal class WearableUIController : MonoBehaviour
	{
		public static GameObject prefab;

		public static WearableUIController? Instance;

		[SerializeField]
		private GameObject radialMenuPrefab = null;

		[SerializeField]
		private GameObject radialMenuElementPrefab = null;

		[SerializeField]
		private Transform canvas = null;

		[SerializeField]
		private Image icon = null;

		[SerializeField]
		private TMP_Text iconLabel = null;

		[SerializeField]
		private Animator animator = null;

		[SerializeField]
		private Sprite[] bodyOutlineParts = null;

		[HideInInspector]
		public RadialMenu? radial;

		private Image? selfHighlight;

		private CanvasGroup? selfHighlightCanvasGroup;

		private bool openingUI;

		private bool iconEnabled;

		public bool uiOpen => (Object)(object)radial != (Object)null;

		public static void Init()
		{
			if (!((Object)(object)Instance != (Object)null))
			{
				if ((Object)(object)prefab == (Object)null)
				{
					Plugin.logger.LogError((object)"Could not instantiate UI");
				}
				else
				{
					Object.Instantiate<GameObject>(prefab, ((Component)Plugin.localPlayer).transform);
				}
			}
		}

		public void OnDestroy()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Expected O, but got Unknown
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Plugin.logger.LogDebug((object)"Destroying UIController");
				Instance = null;
				PlayerWearables.OnWearablesUpdate.RemoveListener(new UnityAction(UpdateIcon));
			}
		}

		public void Start()
		{
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Expected O, but got Unknown
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			Plugin.logger.LogDebug((object)"UIController: Start()");
			if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
				return;
			}
			Instance = this;
			Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
			CanvasGroup selfRedCanvasGroup = HUDManager.Instance.selfRedCanvasGroup;
			GameObject val = ((selfRedCanvasGroup != null) ? ((Component)selfRedCanvasGroup).gameObject : null);
			if ((Object)(object)val != (Object)null)
			{
				GameObject val2 = Object.Instantiate<GameObject>(val, val.transform.parent);
				((Object)val2).name = "WISelfHighlight";
				selfHighlight = val2.GetComponent<Image>();
				selfHighlightCanvasGroup = val2.GetComponent<CanvasGroup>();
				selfHighlightCanvasGroup.alpha = 0f;
				selfHighlight.sprite = null;
				((Graphic)selfHighlight).color = Color.white;
			}
			PlayerWearables.OnWearablesUpdate.AddListener(new UnityAction(UpdateIcon));
			Plugin.logger.LogDebug((object)"UIControllerScript: Start() complete");
		}

		public void Update()
		{
			iconLabel.text = "[" + WearableItemsInputs.Instance.OpenUIKey_BindingDisplayString + "]";
			if (uiOpen && (((ButtonControl)Keyboard.current.escapeKey).wasPressedThisFrame || ((ButtonControl)Keyboard.current.tabKey).wasPressedThisFrame))
			{
				HideUI();
			}
			if (WearableItemsInputs.Instance.OpenUIKey.WasPressedThisFrame() && Plugin.localPlayer.CheckConditionsForEmote() && PlayerWearables.GetWearables(Plugin.localPlayer).Count > 0)
			{
				if (!uiOpen)
				{
					ShowUI();
				}
				else
				{
					HideUI();
				}
			}
		}

		public void UpdateIcon()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			int count = PlayerWearables.GetWearables(Plugin.localPlayer).Count;
			Plugin.logger.LogDebug((object)("Updating icon, wearables count: " + count));
			((Behaviour)icon).enabled = count > 0;
			((Behaviour)iconLabel).enabled = count > 0;
			((Graphic)icon).color = Color32.op_Implicit(new Color32((byte)Random.Range(0, 255), (byte)Random.Range(0, 255), (byte)Random.Range(0, 255), (byte)200));
			HUDManager.Instance.DisplayTip("WearableItemsAPI", "Press " + WearableItemsInputs.Instance.OpenUIKey_BindingDisplayString + " to open the Wearable Items UI", false, true, "WearableItemsAPITip1");
		}

		public void ShowUI()
		{
			Plugin.logger.LogDebug((object)"Showing UI");
			Plugin.localPlayer.disableMoveInput = true;
			Plugin.localPlayer.disableInteract = true;
			Plugin.localPlayer.disableLookInput = true;
			Cursor.lockState = (CursorLockMode)0;
			Cursor.visible = true;
			openingUI = true;
			animator.SetBool("open", true);
		}

		public void HideUI()
		{
			Plugin.logger.LogDebug((object)"Hiding UI");
			Plugin.localPlayer.disableMoveInput = false;
			Plugin.localPlayer.disableInteract = false;
			Plugin.localPlayer.disableLookInput = false;
			Cursor.lockState = (CursorLockMode)1;
			Cursor.visible = false;
			openingUI = false;
			RadialMenu? radialMenu = radial;
			Object.Destroy((Object)(object)((radialMenu != null) ? ((Component)radialMenu).gameObject : null));
			radial = null;
			animator.SetBool("open", false);
			SetBodyOutline((WearableSlot)(-1));
		}

		public void BuildUI()
		{
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Expected O, but got Unknown
			if (!openingUI)
			{
				return;
			}
			if ((Object)(object)radial != (Object)null)
			{
				Object.Destroy((Object)(object)((Component)radial).gameObject);
				radial = null;
			}
			radial = Object.Instantiate<GameObject>(radialMenuPrefab, canvas).GetComponent<RadialMenu>();
			foreach (WearableObject item in PlayerWearables.GetWearables(Plugin.localPlayer).ToList())
			{
				RadialMenuElement element = Object.Instantiate<GameObject>(radialMenuElementPrefab, radial.elementsContainer).GetComponent<RadialMenuElement>();
				element.item = item;
				element.label = ((GrabbableObject)item).itemProperties.itemName;
				element.icon.sprite = (((Object)(object)item.wearableItemProperties.icon != (Object)null) ? item.wearableItemProperties.icon : ((GrabbableObject)item).itemProperties.itemIcon);
				((UnityEvent)element.button.onClick).AddListener((UnityAction)delegate
				{
					OnClickElement(element);
				});
				radial.elements.Add(element);
			}
			radial.Rebuild();
		}

		public void OnClickElement(RadialMenuElement element)
		{
			element.item.UnWearItem();
			radial.elements.Remove(element);
			Object.Destroy((Object)(object)((Component)element).gameObject);
			HideUI();
		}

		public void SetBodyOutline(WearableSlot slot)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Expected I4, but got Unknown
			if (!((Object)(object)selfHighlight == (Object)null) && !((Object)(object)selfHighlightCanvasGroup == (Object)null))
			{
				int num = (int)slot;
				selfHighlight.sprite = ((num >= 0) ? bodyOutlineParts[num] : null);
				selfHighlightCanvasGroup.alpha = ((num >= 0) ? 1 : 0);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Snowlance.WearableItemsAPI.UI";

		public const string PLUGIN_NAME = "WearableItemsAPI.UI";

		public const string PLUGIN_VERSION = "0.2.0";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}