Decompiled source of UtilitySlotEditor v1.0.2

UtilitySlotEditor.dll

Decompiled 3 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using GameNetcodeStuff;
using HarmonyLib;
using TMPro;
using Unity.Netcode;
using UnityEngine;
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: AssemblyTitle("UtilitySlotEditor")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UtilitySlotEditor")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("3431d29f-2b8d-4427-880f-be8ed417bbc7")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace UtilitySlotEditor;

[BepInPlugin("azumi.utilitysloteditor", "UtilitySlotEditor", "1.0.2")]
public class Plugin : BaseUnityPlugin
{
	internal static ManualLogSource Log;

	internal static ConfigFile ConfigFile;

	private Harmony harmony;

	private void Awake()
	{
		//IL_0029: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		ConfigFile = ((BaseUnityPlugin)this).Config;
		UtilitySlotEditorConfig.Init(((BaseUnityPlugin)this).Config);
		harmony = new Harmony("azumi.utilitysloteditor");
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"UtilitySlotEditor loaded.");
	}
}
public static class UtilitySlotEditorConfig
{
	public static ConfigEntry<Key> EditKey;

	public static ConfigEntry<Key> ResetKey;

	public static ConfigEntry<float> PositionX;

	public static ConfigEntry<float> PositionY;

	public static ConfigEntry<bool> PositionInitialized;

	public static ConfigEntry<bool> DisableUtilitySlot;

	public static ConfigEntry<bool> ShowUtilitySlotKeyText;

	public static ConfigEntry<float> UtilityFrameSize;

	public static void Init(ConfigFile config)
	{
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Expected O, but got Unknown
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Expected O, but got Unknown
		//IL_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f7: Expected O, but got Unknown
		EditKey = config.Bind<Key>("Controls", "Edit Key", (Key)101, "Toggle Utility Slot edit mode.");
		ResetKey = config.Bind<Key>("Controls", "Reset Key", (Key)102, "Reset Utility Slot position. Only works while Edit Mode is active.");
		PositionX = config.Bind<float>("Position", "Position X", 0f, new ConfigDescription("Saved Utility Slot anchored X position.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-430f, 430f), Array.Empty<object>()));
		PositionY = config.Bind<float>("Position", "Position Y", 0f, new ConfigDescription("Saved Utility Slot anchored Y position.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(-237f, 237f), Array.Empty<object>()));
		PositionInitialized = config.Bind<bool>("Position", "Position Initialized", false, "Whether Utility Slot position has been initialized.");
		UtilityFrameSize = config.Bind<float>("General", "Utility Frame Size", 0f, new ConfigDescription("Change the frame size of the Utility Slot. 0 = Vanilla Utility Frame, 1 = Vanilla Inventory Frame.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
		ShowUtilitySlotKeyText = config.Bind<bool>("General", "Show Utility Slot Key Text", true, "Show the Utility Slot key text.");
		DisableUtilitySlot = config.Bind<bool>("General", "Disable Utility Slot", false, "Disable the Utility Slot locally without changing its hierarchy.");
		Plugin.Log.LogInfo((object)("[Config] Config file path = " + config.ConfigFilePath));
		Plugin.Log.LogInfo((object)$"[Config] Loaded Position X = {PositionX.Value}");
		Plugin.Log.LogInfo((object)$"[Config] Loaded Position Y = {PositionY.Value}");
		Plugin.Log.LogInfo((object)("[Config] Position Initialized = " + $"{PositionInitialized.Value}"));
	}

	public static Vector2 GetPosition()
	{
		//IL_0015: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		return new Vector2(PositionX.Value, PositionY.Value);
	}

	public static bool HasSavedPosition()
	{
		return PositionInitialized.Value;
	}

	public static void InitializeFromVanillaPosition(Vector2 vanillaPosition)
	{
		//IL_0043: 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_00af: Unknown result type (might be due to invalid IL or missing references)
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		if (PositionInitialized.Value)
		{
			Plugin.Log.LogInfo((object)("[Config] Saved Utility Slot position found: " + $"{GetPosition()}"));
			return;
		}
		PositionX.Value = Mathf.Clamp(vanillaPosition.x, -430f, 430f);
		PositionY.Value = Mathf.Clamp(vanillaPosition.y, -237f, 237f);
		PositionInitialized.Value = true;
		Save();
		Plugin.Log.LogInfo((object)"[Config] No saved Utility Slot position found.");
		Plugin.Log.LogInfo((object)("[Config] Vanilla position detected: " + $"{vanillaPosition}"));
		Plugin.Log.LogInfo((object)"[Config] Vanilla position saved as initial position.");
	}

	public static void SetPosition(Vector2 position)
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		float num = Mathf.Clamp(position.x, -430f, 430f);
		float num2 = Mathf.Clamp(position.y, -237f, 237f);
		PositionX.Value = num;
		PositionY.Value = num2;
		PositionInitialized.Value = true;
		Save();
		Plugin.Log.LogInfo((object)("[Config] Position saved: " + $"X={num:F3}, Y={num2:F3}"));
	}

	public static void Save()
	{
		if (Plugin.ConfigFile == null)
		{
			Plugin.Log.LogError((object)"[Config] ConfigFile is null.");
			return;
		}
		try
		{
			Plugin.ConfigFile.Save();
			Plugin.Log.LogInfo((object)"[Config] ConfigFile.Save() completed.");
			Plugin.Log.LogInfo((object)("[Config] Saved Position = " + $"({PositionX.Value:F3}, " + $"{PositionY.Value:F3})"));
			Plugin.Log.LogInfo((object)("[Config] Saved PositionInitialized = " + $"{PositionInitialized.Value}"));
		}
		catch (Exception arg)
		{
			Plugin.Log.LogError((object)$"[Config] Save failed: {arg}");
		}
	}
}
public static class UtilityEditState
{
	public static bool IsEditing;
}
[HarmonyPatch(typeof(HUDManager), "Start")]
public static class HUDManagerStartPatch
{
	private static bool eventsRegistered;

	private static void Postfix(HUDManager __instance)
	{
		if (!eventsRegistered)
		{
			eventsRegistered = true;
			UtilitySlotEditorConfig.UtilityFrameSize.SettingChanged += delegate
			{
				UtilitySlotController.RefreshFrameSize();
			};
			UtilitySlotEditorConfig.ShowUtilitySlotKeyText.SettingChanged += delegate
			{
				UtilitySlotController.RefreshKeyText();
			};
			UtilitySlotEditorConfig.DisableUtilitySlot.SettingChanged += delegate
			{
				UtilitySlotController.HandleUtilityEnabledStateChanged();
			};
		}
		UtilitySlotController.Attach(__instance);
	}
}
[HarmonyPatch(typeof(HUDManager), "Update")]
public static class HUDManagerUpdatePatch
{
	private static void Postfix()
	{
		//IL_0019: 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)
		if (Keyboard.current != null)
		{
			if (((ButtonControl)Keyboard.current[UtilitySlotEditorConfig.EditKey.Value]).wasPressedThisFrame)
			{
				ToggleEditMode();
			}
			if (UtilityEditState.IsEditing && ((ButtonControl)Keyboard.current[UtilitySlotEditorConfig.ResetKey.Value]).wasPressedThisFrame)
			{
				UtilitySlotController.ResetPosition();
				ShowTip("Utility Slot", "Position Reset.");
			}
		}
	}

	private static void ToggleEditMode()
	{
		UtilityEditState.IsEditing = !UtilityEditState.IsEditing;
		if (UtilityEditState.IsEditing)
		{
			UtilitySlotController.BeginEdit();
			ShowTip("Utility Slot", "Edit Mode ON.\nDrag the Utility Slot with the cursor.");
		}
		else
		{
			UtilitySlotController.EndEdit();
			ShowTip("Utility Slot", "Edit Mode OFF.");
		}
	}

	private static void ShowTip(string title, string message)
	{
		if (!((Object)(object)HUDManager.Instance == (Object)null))
		{
			HUDManager.Instance.DisplayTip(title, message, false, false, "LC_Tip1");
		}
	}
}
public class UtilitySlotController : MonoBehaviour
{
	private class VanillaImageState
	{
		public Image Image;

		public Type Type;

		public float PixelsPerUnitMultiplier;
	}

	private class VanillaRectState
	{
		public RectTransform Rect;

		public Vector2 SizeDelta;

		public Vector2 AnchoredPosition;

		public Vector3 LocalScale;

		public float FontSize;

		public bool HasFontSize;
	}

	private static UtilitySlotController Instance;

	private static HUDManager hud;

	private static RectTransform utilityRect;

	private static float configApplyTimer;

	private static Vector2 vanillaPosition;

	private static Vector2 lastSyncedConfigPosition;

	private static bool configPositionInitialized;

	private const float UtilityFrameVisualCorrection = 1.7f;

	private static Vector2 vanillaUtilityFrameSize;

	private static Vector2 vanillaInventoryFrameSize;

	private static Vector3 vanillaUtilityScale;

	private static Image utilityFrameImage;

	private static float vanillaUtilityFramePixelsPerUnitMultiplier = 1f;

	private static readonly List<VanillaImageState> vanillaUtilityImages = new List<VanillaImageState>();

	private static TMP_Text utilitySlotKeyText;

	private static GameObject editOverlayObject;

	private static Image editOverlayImage;

	private static readonly Color EditModeColor = new Color(0f, 1f, 0f, 0.35f);

	private static readonly Color EditModeDraggingColor = new Color(0f, 0.55f, 0f, 0.65f);

	private static bool initialized;

	private static readonly List<VanillaRectState> vanillaUtilityChildren = new List<VanillaRectState>();

	private void Update()
	{
		SyncConfigPosition();
		if (initialized && !((Object)(object)utilityRect == (Object)null))
		{
			configApplyTimer += Time.unscaledDeltaTime;
			if (configApplyTimer < 1f)
			{
				ApplyConfigPosition();
			}
		}
	}

	public static void Attach(HUDManager instance)
	{
		//IL_011e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_018e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0238: Unknown result type (might be due to invalid IL or missing references)
		//IL_023d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0260: Unknown result type (might be due to invalid IL or missing references)
		//IL_0265: Unknown result type (might be due to invalid IL or missing references)
		//IL_026f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0274: Unknown result type (might be due to invalid IL or missing references)
		//IL_0279: 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_0302: Unknown result type (might be due to invalid IL or missing references)
		//IL_032b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0354: Unknown result type (might be due to invalid IL or missing references)
		//IL_0399: Unknown result type (might be due to invalid IL or missing references)
		//IL_03a0: Expected O, but got Unknown
		if ((Object)(object)instance == (Object)null)
		{
			Plugin.Log.LogWarning((object)"HUDManager is null.");
			return;
		}
		if (initialized && (Object)(object)hud == (Object)(object)instance && (Object)(object)utilityRect != (Object)null)
		{
			ApplyConfigPosition(force: true);
			RefreshFrameSize();
			RefreshUtilityEnabledState();
			RefreshKeyText();
			return;
		}
		Plugin.Log.LogInfo((object)"UtilitySlotEditor: Attaching / Reattaching UI.");
		hud = instance;
		utilityRect = null;
		utilitySlotKeyText = null;
		DestroyEditOverlay();
		vanillaUtilityChildren.Clear();
		initialized = false;
		configPositionInitialized = false;
		if ((Object)(object)hud.itemOnlySlotIconFrame == (Object)null)
		{
			Plugin.Log.LogWarning((object)"itemOnlySlotIconFrame was not found.");
			return;
		}
		utilityRect = ((Graphic)hud.itemOnlySlotIconFrame).rectTransform;
		if ((Object)(object)utilityRect == (Object)null)
		{
			Plugin.Log.LogWarning((object)"Utility Slot RectTransform was not found.");
			return;
		}
		utilitySlotKeyText = ((Component)utilityRect).GetComponentInChildren<TMP_Text>(true);
		vanillaUtilityFrameSize = utilityRect.sizeDelta;
		utilityFrameImage = ((Component)utilityRect).GetComponent<Image>();
		if ((Object)(object)utilityFrameImage != (Object)null)
		{
			vanillaUtilityFramePixelsPerUnitMultiplier = utilityFrameImage.pixelsPerUnitMultiplier;
			Plugin.Log.LogInfo((object)("Vanilla Utility Frame Image = " + ((Object)utilityFrameImage).name));
			Plugin.Log.LogInfo((object)("Vanilla Frame Image Type = " + $"{utilityFrameImage.type}"));
			Plugin.Log.LogInfo((object)("Vanilla Frame PixelsPerUnitMultiplier = " + $"{vanillaUtilityFramePixelsPerUnitMultiplier}"));
		}
		else
		{
			Plugin.Log.LogWarning((object)"Utility Frame Image was not found on utilityRect.");
		}
		CaptureVanillaUtilityChildren();
		CaptureVanillaUtilityImages();
		if (hud.itemSlotIconFrames != null && hud.itemSlotIconFrames.Length != 0 && (Object)(object)hud.itemSlotIconFrames[0] != (Object)null)
		{
			vanillaInventoryFrameSize = ((Graphic)hud.itemSlotIconFrames[0]).rectTransform.sizeDelta;
			vanillaPosition = utilityRect.anchoredPosition;
			vanillaUtilityScale = ((Transform)utilityRect).localScale;
			UtilitySlotEditorConfig.InitializeFromVanillaPosition(vanillaPosition);
			initialized = true;
			Plugin.Log.LogInfo((object)("Utility Object = " + ((Object)utilityRect).name));
			ManualLogSource log = Plugin.Log;
			Transform parent = ((Transform)utilityRect).parent;
			log.LogInfo((object)("Utility Parent = " + ((parent != null) ? ((Object)parent).name : null)));
			Plugin.Log.LogInfo((object)$"Vanilla Anchored Position = {vanillaPosition}");
			Plugin.Log.LogInfo((object)("Vanilla Utility Frame Size = " + $"{vanillaUtilityFrameSize}"));
			Plugin.Log.LogInfo((object)("Vanilla Inventory Frame Size = " + $"{vanillaInventoryFrameSize}"));
			Plugin.Log.LogInfo((object)$"Utility Scale = {((Transform)utilityRect).localScale}");
			ApplyConfigPosition(force: true);
			RefreshFrameSize();
			RefreshUtilityEnabledState();
			RefreshKeyText();
			if ((Object)(object)Instance == (Object)null)
			{
				GameObject val = new GameObject("UtilitySlotEditorController");
				Object.DontDestroyOnLoad((Object)(object)val);
				Instance = val.AddComponent<UtilitySlotController>();
			}
			Plugin.Log.LogInfo((object)"UtilitySlotEditor successfully attached to current HUDManager.");
		}
		else
		{
			Plugin.Log.LogWarning((object)"Vanilla Inventory Frame was not found.");
		}
	}

	private static void CaptureVanillaUtilityChildren()
	{
		//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_007b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		vanillaUtilityChildren.Clear();
		if ((Object)(object)utilityRect == (Object)null)
		{
			return;
		}
		RectTransform[] componentsInChildren = ((Component)utilityRect).GetComponentsInChildren<RectTransform>(true);
		RectTransform[] array = componentsInChildren;
		foreach (RectTransform val in array)
		{
			if (!((Object)(object)val == (Object)(object)utilityRect))
			{
				TMP_Text component = ((Component)val).GetComponent<TMP_Text>();
				VanillaRectState vanillaRectState = new VanillaRectState();
				vanillaRectState.Rect = val;
				vanillaRectState.SizeDelta = val.sizeDelta;
				vanillaRectState.AnchoredPosition = val.anchoredPosition;
				vanillaRectState.LocalScale = ((Transform)val).localScale;
				if ((Object)(object)component != (Object)null)
				{
					vanillaRectState.HasFontSize = true;
					vanillaRectState.FontSize = component.fontSize;
				}
				vanillaUtilityChildren.Add(vanillaRectState);
			}
		}
		Plugin.Log.LogInfo((object)($"Captured {vanillaUtilityChildren.Count} " + "Utility child RectTransforms."));
	}

	private static void CaptureVanillaUtilityImages()
	{
		//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_00b6: Unknown result type (might be due to invalid IL or missing references)
		vanillaUtilityImages.Clear();
		if ((Object)(object)utilityRect == (Object)null)
		{
			return;
		}
		Image[] componentsInChildren = ((Component)utilityRect).GetComponentsInChildren<Image>(true);
		Image[] array = componentsInChildren;
		foreach (Image val in array)
		{
			if (!((Object)(object)val == (Object)null))
			{
				VanillaImageState vanillaImageState = new VanillaImageState();
				vanillaImageState.Image = val;
				vanillaImageState.Type = val.type;
				vanillaImageState.PixelsPerUnitMultiplier = val.pixelsPerUnitMultiplier;
				vanillaUtilityImages.Add(vanillaImageState);
				Plugin.Log.LogInfo((object)("[Utility Image] Captured = " + ((Object)val).name + ", " + $"Type={val.type}, " + $"PPU={val.pixelsPerUnitMultiplier:F4}"));
			}
		}
		Plugin.Log.LogInfo((object)("[Utility Image] Captured " + $"{vanillaUtilityImages.Count} Images."));
	}

	private static void CreateEditOverlay()
	{
		//IL_005c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Expected O, but got Unknown
		//IL_0088: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00aa: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)utilityRect == (Object)null)
		{
			return;
		}
		if ((Object)(object)editOverlayObject != (Object)null)
		{
			editOverlayObject.SetActive(true);
			if ((Object)(object)editOverlayImage != (Object)null)
			{
				((Graphic)editOverlayImage).color = EditModeColor;
			}
			return;
		}
		editOverlayObject = new GameObject("UtilitySlotEditOverlay");
		editOverlayObject.transform.SetParent((Transform)(object)utilityRect, false);
		RectTransform val = editOverlayObject.AddComponent<RectTransform>();
		val.anchorMin = Vector2.zero;
		val.anchorMax = Vector2.one;
		val.pivot = new Vector2(0.5f, 0.5f);
		val.offsetMin = Vector2.zero;
		val.offsetMax = Vector2.zero;
		editOverlayImage = editOverlayObject.AddComponent<Image>();
		((Graphic)editOverlayImage).color = EditModeColor;
		((Graphic)editOverlayImage).raycastTarget = false;
		editOverlayObject.transform.SetAsLastSibling();
		Plugin.Log.LogInfo((object)"[Edit Visual] Utility Slot edit overlay created.");
	}

	private static void DestroyEditOverlay()
	{
		if ((Object)(object)editOverlayObject != (Object)null)
		{
			Object.Destroy((Object)(object)editOverlayObject);
		}
		editOverlayObject = null;
		editOverlayImage = null;
		Plugin.Log.LogInfo((object)"[Edit Visual] Utility Slot edit overlay destroyed.");
	}

	public static void SetEditOverlayDragging(bool dragging)
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_001a: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)editOverlayImage == (Object)null))
		{
			((Graphic)editOverlayImage).color = (dragging ? EditModeDraggingColor : EditModeColor);
		}
	}

	private static void ApplyUtilityScale(Vector2 targetFrameSize)
	{
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_005d: Unknown result type (might be due to invalid IL or missing references)
		//IL_007e: 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_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e8: Invalid comparison between Unknown and I4
		//IL_025e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0276: Unknown result type (might be due to invalid IL or missing references)
		//IL_0177: 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_018c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0192: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)utilityRect == (Object)null || vanillaUtilityFrameSize.x <= 0f || vanillaUtilityFrameSize.y <= 0f)
		{
			return;
		}
		float num = targetFrameSize.x / vanillaUtilityFrameSize.x;
		float num2 = targetFrameSize.y / vanillaUtilityFrameSize.y;
		float num3 = (num + num2) * 0.5f;
		utilityRect.sizeDelta = targetFrameSize;
		((Transform)utilityRect).localScale = vanillaUtilityScale;
		float num4 = Mathf.Max(num3, 0.0001f);
		foreach (VanillaImageState vanillaUtilityImage in vanillaUtilityImages)
		{
			if (vanillaUtilityImage != null && !((Object)(object)vanillaUtilityImage.Image == (Object)null))
			{
				Image image = vanillaUtilityImage.Image;
				if ((int)vanillaUtilityImage.Type == 1)
				{
					image.pixelsPerUnitMultiplier = vanillaUtilityImage.PixelsPerUnitMultiplier / num4;
				}
				else
				{
					image.pixelsPerUnitMultiplier = vanillaUtilityImage.PixelsPerUnitMultiplier;
				}
			}
		}
		foreach (VanillaRectState vanillaUtilityChild in vanillaUtilityChildren)
		{
			if (vanillaUtilityChild == null || (Object)(object)vanillaUtilityChild.Rect == (Object)null)
			{
				continue;
			}
			RectTransform rect = vanillaUtilityChild.Rect;
			rect.sizeDelta = vanillaUtilityChild.SizeDelta * num3;
			rect.anchoredPosition = vanillaUtilityChild.AnchoredPosition * num3;
			((Transform)rect).localScale = vanillaUtilityChild.LocalScale;
			if (vanillaUtilityChild.HasFontSize)
			{
				TMP_Text component = ((Component)rect).GetComponent<TMP_Text>();
				if ((Object)(object)component != (Object)null)
				{
					component.fontSize = vanillaUtilityChild.FontSize * num3;
				}
			}
		}
		Plugin.Log.LogInfo((object)("[Utility UI] VanillaFrame=" + $"{vanillaUtilityFrameSize.x:F3} x " + $"{vanillaUtilityFrameSize.y:F3}, " + "TargetFrame=" + $"{targetFrameSize.x:F3} x " + $"{targetFrameSize.y:F3}, " + $"Scale={num3:F6}, " + "Correction=" + $"{1.7f:F6}"));
	}

	private static Vector2 GetMaximumFrameSize()
	{
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0033: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Unknown result type (might be due to invalid IL or missing references)
		if (vanillaInventoryFrameSize.x <= 0f || vanillaInventoryFrameSize.y <= 0f)
		{
			return vanillaUtilityFrameSize;
		}
		return vanillaInventoryFrameSize * 1.7f;
	}

	private static Vector2 GetTargetFrameSize()
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0030: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_000d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0012: 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)
		if (!initialized)
		{
			return vanillaUtilityFrameSize;
		}
		float num = Mathf.Clamp01(UtilitySlotEditorConfig.UtilityFrameSize.Value);
		Vector2 maximumFrameSize = GetMaximumFrameSize();
		return Vector2.Lerp(vanillaUtilityFrameSize, maximumFrameSize, num);
	}

	public static void RefreshFrameSize()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: 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_0080: Unknown result type (might be due to invalid IL or missing references)
		if (initialized && !((Object)(object)utilityRect == (Object)null))
		{
			Vector2 targetFrameSize = GetTargetFrameSize();
			ApplyUtilityScale(targetFrameSize);
			if ((Object)(object)editOverlayObject != (Object)null)
			{
				editOverlayObject.transform.SetAsLastSibling();
			}
			Plugin.Log.LogInfo((object)("Utility Frame Size = " + $"{targetFrameSize.x:F3} x " + $"{targetFrameSize.y:F3} " + "(Slider = " + $"{UtilitySlotEditorConfig.UtilityFrameSize.Value:F3})"));
		}
	}

	private static void DropExistingUtilityItem()
	{
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		PlayerControllerB val = GameNetworkManager.Instance?.localPlayerController;
		if ((Object)(object)val == (Object)null)
		{
			Plugin.Log.LogWarning((object)"[Utility Disable] Local player controller is null.");
			return;
		}
		GrabbableObject itemOnlySlot = val.ItemOnlySlot;
		if (!((Object)(object)itemOnlySlot == (Object)null))
		{
			Plugin.Log.LogInfo((object)("[Utility Disable] Utility Slot disabled while holding item: " + itemOnlySlot.itemProperties.itemName));
			val.DiscardHeldObject(false, (NetworkObject)null, Vector3.zero, true);
		}
	}

	public static void HandleUtilityEnabledStateChanged()
	{
		if (initialized && !((Object)(object)utilityRect == (Object)null))
		{
			if (UtilitySlotEditorConfig.DisableUtilitySlot.Value)
			{
				DropExistingUtilityItem();
			}
			RefreshUtilityEnabledState();
		}
	}

	public static void RefreshUtilityEnabledState()
	{
		if (initialized && !((Object)(object)utilityRect == (Object)null))
		{
			bool value = UtilitySlotEditorConfig.DisableUtilitySlot.Value;
			((Component)utilityRect).gameObject.SetActive(!value);
			Plugin.Log.LogInfo((object)$"Utility Slot active = {!value}");
		}
	}

	public static void RefreshKeyText()
	{
		if (!((Object)(object)utilitySlotKeyText == (Object)null))
		{
			((Component)utilitySlotKeyText).gameObject.SetActive(UtilitySlotEditorConfig.ShowUtilitySlotKeyText.Value);
			Plugin.Log.LogInfo((object)("Utility Slot Key Text active = " + $"{UtilitySlotEditorConfig.ShowUtilitySlotKeyText.Value}"));
		}
	}

	public static void BeginEdit()
	{
		//IL_006f: 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)
		if (!initialized || (Object)(object)utilityRect == (Object)null)
		{
			Plugin.Log.LogWarning((object)"Cannot begin edit: Utility Slot not initialized.");
			return;
		}
		Cursor.visible = true;
		Cursor.lockState = (CursorLockMode)0;
		CreateEditOverlay();
		SetEditOverlayDragging(dragging: false);
		Plugin.Log.LogInfo((object)"UtilitySlotEditor: Edit on.");
		Plugin.Log.LogInfo((object)("Current Position = " + $"{utilityRect.anchoredPosition}"));
		Plugin.Log.LogInfo((object)("Current Frame Size = " + $"{utilityRect.sizeDelta}"));
	}

	public static void EndEdit()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_0027: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_006d: Unknown result type (might be due to invalid IL or missing references)
		if (initialized && !((Object)(object)utilityRect == (Object)null))
		{
			Vector2 anchoredPosition = utilityRect.anchoredPosition;
			UtilitySlotEditorConfig.SetPosition(anchoredPosition);
			lastSyncedConfigPosition = anchoredPosition;
			configPositionInitialized = true;
			Cursor.visible = false;
			SetEditOverlayDragging(dragging: false);
			DestroyEditOverlay();
			Plugin.Log.LogInfo((object)"UtilitySlotEditor: Edit mode disabled.");
			Plugin.Log.LogInfo((object)("[Position] Saved on Edit Mode end: " + $"{anchoredPosition}"));
		}
	}

	public static void ResetPosition()
	{
		//IL_0021: Unknown result type (might be due to invalid IL or missing references)
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0056: Unknown result type (might be due to invalid IL or missing references)
		if (initialized && !((Object)(object)utilityRect == (Object)null))
		{
			utilityRect.anchoredPosition = vanillaPosition;
			UtilitySlotEditorConfig.SetPosition(vanillaPosition);
			lastSyncedConfigPosition = vanillaPosition;
			configPositionInitialized = true;
			Plugin.Log.LogInfo((object)("Utility Slot reset to vanilla position: " + $"{vanillaPosition}"));
		}
	}

	public static void ApplyConfigPosition(bool force = false)
	{
		//IL_001f: 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_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_0044: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_007c: 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_0097: Unknown result type (might be due to invalid IL or missing references)
		if (initialized && !((Object)(object)utilityRect == (Object)null))
		{
			Vector2 position = UtilitySlotEditorConfig.GetPosition();
			bool flag = Vector2.Distance(utilityRect.anchoredPosition, position) > 0.001f;
			bool flag2 = !configPositionInitialized || Vector2.Distance(position, lastSyncedConfigPosition) > 0.001f;
			if (force || flag || flag2)
			{
				utilityRect.anchoredPosition = position;
				lastSyncedConfigPosition = position;
				configPositionInitialized = true;
				Plugin.Log.LogInfo((object)("[Position Sync] Applied Config Position = " + $"{position}"));
			}
		}
	}

	private static void SyncConfigPosition()
	{
		//IL_002f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: Unknown result type (might be due to invalid IL or missing references)
		//IL_003c: 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_0057: 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_0079: 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_0081: 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)
		if (initialized && !((Object)(object)utilityRect == (Object)null) && !UtilityEditState.IsEditing)
		{
			Vector2 position = UtilitySlotEditorConfig.GetPosition();
			bool flag = !configPositionInitialized || Vector2.Distance(position, lastSyncedConfigPosition) > 0.001f;
			bool flag2 = Vector2.Distance(utilityRect.anchoredPosition, position) > 0.001f;
			if (flag || flag2)
			{
				utilityRect.anchoredPosition = position;
				lastSyncedConfigPosition = position;
				configPositionInitialized = true;
				Plugin.Log.LogInfo((object)("[Position Sync] Applied Config Position = " + $"{position}"));
			}
		}
	}

	public static void CommitPosition(Vector2 position)
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0023: Unknown result type (might be due to invalid IL or missing references)
		//IL_0028: Unknown result type (might be due to invalid IL or missing references)
		//IL_002e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0035: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Unknown result type (might be due to invalid IL or missing references)
		if (initialized && !((Object)(object)utilityRect == (Object)null))
		{
			UtilitySlotEditorConfig.SetPosition(position);
			Vector2 position2 = UtilitySlotEditorConfig.GetPosition();
			utilityRect.anchoredPosition = position2;
			lastSyncedConfigPosition = position2;
			configPositionInitialized = true;
			Plugin.Log.LogInfo((object)("[Position] Utility Slot position committed: " + $"{position2}"));
		}
	}

	public static RectTransform GetUtilityRect()
	{
		return utilityRect;
	}

	public static Vector2 GetVanillaPosition()
	{
		//IL_0001: Unknown result type (might be due to invalid IL or missing references)
		//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		return vanillaPosition;
	}
}
[HarmonyPatch]
public static class UtilitySlotFunctionPatch
{
	private static bool IsLocalPlayer(PlayerControllerB player)
	{
		return (Object)(object)player != (Object)null && (Object)(object)player == (Object)(object)GameNetworkManager.Instance?.localPlayerController;
	}

	[HarmonyPatch(typeof(PlayerControllerB), "FirstEmptyItemSlot")]
	[HarmonyPrefix]
	private static bool FirstEmptyItemSlotPrefix(PlayerControllerB __instance, GrabbableObject attemptingGrab, ref int __result)
	{
		if (!UtilitySlotEditorConfig.DisableUtilitySlot.Value)
		{
			return true;
		}
		if (!IsLocalPlayer(__instance))
		{
			return true;
		}
		if ((Object)(object)__instance == (Object)null || __instance.ItemSlots == null)
		{
			__result = -1;
			return false;
		}
		int currentItemSlot = __instance.currentItemSlot;
		if (currentItemSlot >= 0 && currentItemSlot < __instance.ItemSlots.Length && (Object)(object)__instance.ItemSlots[currentItemSlot] == (Object)null)
		{
			__result = currentItemSlot;
			return false;
		}
		for (int i = 0; i < __instance.ItemSlots.Length; i++)
		{
			if ((Object)(object)__instance.ItemSlots[i] == (Object)null)
			{
				__result = i;
				return false;
			}
		}
		__result = -1;
		return false;
	}

	[HarmonyPatch(typeof(PlayerControllerB), "UseUtilitySlot_performed")]
	[HarmonyPrefix]
	private static bool UseUtilitySlotPrefix(PlayerControllerB __instance)
	{
		if (!UtilitySlotEditorConfig.DisableUtilitySlot.Value)
		{
			return true;
		}
		if (!IsLocalPlayer(__instance))
		{
			return true;
		}
		Plugin.Log.LogDebug((object)"[Utility Disable] Blocked local UseUtilitySlot_performed.");
		return false;
	}
}
public class UtilitySlotDrag : MonoBehaviour
{
	private RectTransform utilityRect;

	private Canvas canvas;

	private bool dragging;

	private Vector2 dragOffset;

	private void Start()
	{
		utilityRect = UtilitySlotController.GetUtilityRect();
		if (!((Object)(object)utilityRect == (Object)null))
		{
			canvas = ((Component)utilityRect).GetComponentInParent<Canvas>();
		}
	}

	private void Update()
	{
		//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_00d9: 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_00ed: Unknown result type (might be due to invalid IL or missing references)
		//IL_015f: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_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_010b: 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_01a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		if (!UtilityEditState.IsEditing)
		{
			if (dragging)
			{
				dragging = false;
				UtilitySlotController.SetEditOverlayDragging(dragging: false);
			}
		}
		else
		{
			if (Mouse.current == null)
			{
				return;
			}
			if ((Object)(object)utilityRect == (Object)null)
			{
				utilityRect = UtilitySlotController.GetUtilityRect();
			}
			if (!((Object)(object)utilityRect == (Object)null))
			{
				if ((Object)(object)canvas == (Object)null)
				{
					canvas = ((Component)utilityRect).GetComponentInParent<Canvas>();
				}
				Camera canvasCamera = GetCanvasCamera();
				Vector2 val = ((InputControl<Vector2>)(object)((Pointer)Mouse.current).position).ReadValue();
				Vector2 val2 = default(Vector2);
				if (!dragging && Mouse.current.leftButton.wasPressedThisFrame && RectTransformUtility.RectangleContainsScreenPoint(utilityRect, val, canvasCamera) && RectTransformUtility.ScreenPointToLocalPointInRectangle(GetParentRect(), val, canvasCamera, ref val2))
				{
					dragOffset = utilityRect.anchoredPosition - val2;
					dragging = true;
					UtilitySlotController.SetEditOverlayDragging(dragging: true);
					Plugin.Log.LogInfo((object)"Utility Slot drag started.");
				}
				Vector2 val3 = default(Vector2);
				if (dragging && RectTransformUtility.ScreenPointToLocalPointInRectangle(GetParentRect(), val, canvasCamera, ref val3))
				{
					utilityRect.anchoredPosition = val3 + dragOffset;
				}
				if (dragging && Mouse.current.leftButton.wasReleasedThisFrame)
				{
					dragging = false;
					UtilitySlotController.SetEditOverlayDragging(dragging: false);
					Vector2 anchoredPosition = utilityRect.anchoredPosition;
					UtilitySlotController.CommitPosition(anchoredPosition);
					Plugin.Log.LogInfo((object)("Utility Slot drag finished: " + $"{anchoredPosition}"));
				}
			}
		}
	}

	private RectTransform GetParentRect()
	{
		if ((Object)(object)utilityRect == (Object)null)
		{
			return null;
		}
		Transform parent = ((Transform)utilityRect).parent;
		return (RectTransform)(object)((parent is RectTransform) ? parent : null);
	}

	private Camera GetCanvasCamera()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0021: Invalid comparison between Unknown and I4
		if ((Object)(object)canvas == (Object)null)
		{
			return null;
		}
		if ((int)canvas.renderMode == 0)
		{
			return null;
		}
		return canvas.worldCamera;
	}
}
[HarmonyPatch(typeof(HUDManager), "Start")]
public static class UtilityDragSetupPatch
{
	private static void Postfix()
	{
		StartCoroutineSafe();
	}

	private static void StartCoroutineSafe()
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Expected O, but got Unknown
		if (!((Object)(object)UtilityDragHost.Instance != (Object)null))
		{
			GameObject val = new GameObject("UtilitySlotEditorDragHost");
			Object.DontDestroyOnLoad((Object)(object)val);
			val.AddComponent<UtilityDragHost>();
		}
	}
}
public class UtilityDragHost : MonoBehaviour
{
	public static UtilityDragHost Instance;

	private UtilitySlotDrag drag;

	private void Awake()
	{
		Instance = this;
		drag = ((Component)this).gameObject.AddComponent<UtilitySlotDrag>();
	}

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