Decompiled source of ZenHoverItem v0.2.5

plugins\ZenHoverItem.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Zen.Config;
using Zen.Lib;
using Zen.Logging;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("ZenHoverItem")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ZenHoverItem")]
[assembly: AssemblyCopyright("Copyright \ufffd  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("0.0.1.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.1.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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]
	[Microsoft.CodeAnalysis.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 ZenHoverItem
{
	internal static class Configs
	{
		public static readonly ConfigEntry<bool> ShowHoverIcons;

		public static readonly ConfigEntry<bool> ShowHoverIconForFuel;

		public static readonly ConfigEntry<bool> ArmorStandShowHoverIcons;

		public static readonly ConfigEntry<bool> ArmorStandShowHoverText;

		public static readonly ConfigEntry<bool> ShowItemDescription;

		public static readonly ConfigEntry<int> ContainerMaxIcons;

		static Configs()
		{
			ShowHoverIcons = Config.Define<bool>(true, "General", "Show Hover Icons", true, "Display hover icons on the crosshair for important pieces such as containers? (Global)");
			ShowHoverIconForFuel = Config.Define<bool>(true, "General", "Show Hover Icon For Fuel", false, "Should the hover icon for fuelable things such as fireplaces, torches, and smelters be shown?\nTypically hover icons are for things you can consume or pickup.");
			ContainerMaxIcons = Config.Define<int>(true, "Containers", "Container Max Icons", 4, Config.AcceptRange<int>(0, 5), "How many icons to display on containers?");
			ArmorStandShowHoverIcons = Config.Define<bool>(true, "Armor Stand", "Show Hover Icons", false, "Display the hover icons for armor stands");
			ArmorStandShowHoverText = Config.Define<bool>(true, "Armor Stand", "Show Hover Text", true, "Display the hover text for armor stands");
			ShowItemDescription = Config.Define<bool>(true, "Items", "Show Item Description", true, "Display the item description when hovering over items on the ground or on stands");
		}
	}
	internal static class Extensions
	{
		internal static string GetHoverDescription(this ItemData itemData)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			if (!Configs.ShowItemDescription.Value)
			{
				return string.Empty;
			}
			string arg = StringExt.Localize(itemData.m_shared.m_description);
			return $"\n\n<color={UIColor.MinorInfo}>{arg}</color>";
		}
	}
	public class HoverItemUI : MonoBehaviour
	{
		private class Element
		{
			public readonly Image Icon;

			public readonly TMP_Text Label;

			private readonly GameObject _element;

			public bool IsVisible
			{
				get
				{
					return _element.activeSelf;
				}
				set
				{
					_element.SetActive(value);
				}
			}

			public Element(int index, Transform root)
			{
				//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
				//IL_0113: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Expected O, but got Unknown
				_element = Object.Instantiate<GameObject>(InventoryGui.instance.m_playerGrid.m_elementPrefab, root);
				((Object)_element).name = "Element_" + index;
				MonoBehaviour[] components = _element.GetComponents<MonoBehaviour>();
				for (int i = 0; i < components.Length; i++)
				{
					Object.Destroy((Object)(object)components[i]);
				}
				Label = ((Component)_element.transform.Find("amount")).GetComponent<TMP_Text>();
				Icon = ((Component)_element.transform.Find("icon")).GetComponent<Image>();
				UI.AddOutline(((Component)Icon).gameObject);
				Transform obj = _element.transform.Find("equiped");
				((Object)obj).name = "background";
				Image component = ((Component)obj).GetComponent<Image>();
				((Graphic)component).color = new Color(0f, 0f, 0f, 0.1f);
				((Behaviour)component).enabled = true;
				foreach (Transform item in _element.transform)
				{
					Transform val = item;
					bool flag;
					switch (((Object)val).name)
					{
					case "icon":
					case "amount":
					case "background":
						flag = true;
						break;
					default:
						flag = false;
						break;
					}
					if (!flag)
					{
						Object.Destroy((Object)(object)((Component)val).gameObject);
					}
				}
			}
		}

		internal const int MaxIcons = 5;

		private const float DefaultScale = 0.8f;

		private const int IconSpacing = 4;

		private static readonly RectOffset PositionOffset = new RectOffset(76, 0, 0, 46);

		private GameObject _crosshairRootAnchor;

		private HorizontalLayoutGroup _layout;

		private readonly List<Element> _elements = new List<Element>();

		private bool _isDirty = true;

		internal static void Init()
		{
			((Component)Hud.instance).gameObject.AddComponent<HoverItemUI>().CreateStructure();
		}

		private void CreateStructure()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			_crosshairRootAnchor = new GameObject("ZenHoverItem");
			_crosshairRootAnchor.transform.SetParent(((Component)Hud.instance.m_crosshair).transform.parent, false);
			_crosshairRootAnchor.transform.localScale = Vector3.one * 0.8f;
			_crosshairRootAnchor.transform.localPosition = Vector3.zero;
			_layout = _crosshairRootAnchor.AddComponent<HorizontalLayoutGroup>();
			((HorizontalOrVerticalLayoutGroup)_layout).childControlWidth = false;
			((HorizontalOrVerticalLayoutGroup)_layout).childControlHeight = false;
			((HorizontalOrVerticalLayoutGroup)_layout).spacing = 4f;
			((LayoutGroup)_layout).padding = PositionOffset;
			((LayoutGroup)_layout).childAlignment = (TextAnchor)6;
			for (int i = 0; i < 5; i++)
			{
				_elements.Add(new Element(i, _crosshairRootAnchor.transform));
			}
		}

		internal static void Shutdown()
		{
			Hud instance = Hud.instance;
			Object.Destroy((Object)(object)((instance != null) ? ((Component)instance).GetComponent<HoverItemUI>() : null));
		}

		private void Update()
		{
			Clear();
		}

		private void OnDestroy()
		{
			Object.Destroy((Object)(object)_crosshairRootAnchor);
		}

		private void Clear()
		{
			if (!_isDirty)
			{
				return;
			}
			foreach (Element element in _elements)
			{
				element.IsVisible = false;
			}
			_isDirty = false;
		}

		public void UpdateHoverIcons(IEnumerable<Sprite?> icons)
		{
			UpdateHoverIcons(icons.Select((Sprite icon) => (icon, "")));
		}

		public void UpdateHoverIcons(IEnumerable<string?> prefabNames)
		{
			UpdateHoverIcons(prefabNames.Select((string prefabName) => (prefabName, "")));
		}

		public void UpdateHoverIcons(IEnumerable<(string? PrefabName, string Label)> elements)
		{
			UpdateHoverIcons(elements.Select<(string, string), (Sprite, string)>(((string PrefabName, string Label) e) => (Utility.IsNullOrWhiteSpace(e.PrefabName) ? null : ItemDataExt.GetIcon(ItemCache.Get(e.PrefabName)), e.Label)));
		}

		public void UpdateHoverIcons(IEnumerable<(Sprite? Icon, string Label)> elements)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			foreach (var (tuple2, num) in IEnumerableExt.WithIndex<(Sprite, string)>(elements))
			{
				if (num < 5)
				{
					SetIcon(tuple2.Item1, num, tuple2.Item2);
					continue;
				}
				break;
			}
		}

		private void SetIcon(Sprite? icon, int index, string label, Vector2 offset = default(Vector2), bool flipX = false)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: 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_0031: 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)
			if (Configs.ShowHoverIcons.Value)
			{
				if (flipX)
				{
					Vector3 localScale = _crosshairRootAnchor.transform.localScale;
					Transform transform = _crosshairRootAnchor.transform;
					Vector3 localScale2 = localScale;
					localScale2.x = 0f - localScale.x;
					transform.localScale = localScale2;
				}
				if (index < 5)
				{
					_elements[index].IsVisible = true;
					((Behaviour)_elements[index].Icon).enabled = Object.op_Implicit((Object)(object)icon);
					_elements[index].Icon.sprite = icon;
					((Behaviour)_elements[index].Label).enabled = label != "";
					_elements[index].Label.text = label;
				}
				_isDirty = true;
			}
		}
	}
	public static class ItemCache
	{
		private static readonly Dictionary<string, ItemDrop> PrefabCache = new Dictionary<string, ItemDrop>();

		public static ItemDrop Get(string prefabName)
		{
			//IL_0052: 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_004a: 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)
			prefabName = Utils.GetPrefabName(prefabName);
			if (!PrefabCache.TryGetValue(prefabName, out ItemDrop value))
			{
				Dictionary<string, ItemDrop> prefabCache = PrefabCache;
				string key = prefabName;
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName);
				ItemDrop obj = ((itemPrefab != null) ? itemPrefab.GetComponent<ItemDrop>() : null);
				if (obj == null)
				{
					string text = prefabName;
					Player localPlayer = Player.m_localPlayer;
					throw new MissingItemException(text, (Vector3)((localPlayer != null) ? ((Component)localPlayer).transform.position : default(Vector3)));
				}
				ItemDrop result = obj;
				prefabCache[key] = obj;
				return result;
			}
			return value;
		}
	}
	[BepInPlugin("ZenDragon.ZenHoverItem", "ZenHoverItem", "0.2.5")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[SynchronizationMode(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class Plugin : ZenMod<Plugin>
	{
		public const string PluginName = "ZenHoverItem";

		public const string PluginVersion = "0.2.5";

		public const string PluginGUID = "ZenDragon.ZenHoverItem";

		protected override void Setup()
		{
		}

		protected override void TitleScene(bool isFirstBoot)
		{
		}

		protected override void WorldStart()
		{
			HoverItemUI.Init();
		}

		protected override void Shutdown()
		{
			HoverItemUI.Shutdown();
		}
	}
}
namespace ZenHoverItem.HoverText
{
	[HarmonyPatch]
	public static class ArmorStand_HoverText
	{
		private static readonly List<string> ItemPrefabNames = new List<string>();

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Switch), "GetHoverText")]
		[HarmonyPriority(300)]
		private static void GetHoverText(Switch __instance, ref string __result)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			ArmorStand componentInParent = ((Component)__instance).GetComponentInParent<ArmorStand>();
			if (!Object.op_Implicit((Object)(object)componentInParent) || !componentInParent.m_nview.IsValid())
			{
				return;
			}
			ItemPrefabNames.Clear();
			foreach (var item3 in IEnumerableExt.WithIndex<ArmorStandSlot>((IEnumerable<ArmorStandSlot>)componentInParent.m_slots))
			{
				ArmorStandSlot item = item3.Item1;
				int item2 = item3.Item2;
				string @string = componentInParent.m_nview.GetZDO().GetString(item2 + "_item", "");
				string currentItemName = item.m_currentItemName;
				if (!Utility.IsNullOrWhiteSpace(@string) && !Utility.IsNullOrWhiteSpace(currentItemName))
				{
					if (Configs.ArmorStandShowHoverIcons.Value)
					{
						ItemPrefabNames.Add(@string);
					}
					if (Configs.ArmorStandShowHoverText.Value)
					{
						string arg = Localization.instance.Localize(currentItemName);
						__result += $"\n-  <color={UIColor.MinorInfo}>{arg}</color>";
					}
				}
			}
			if (Configs.ArmorStandShowHoverIcons.Value)
			{
				ItemPrefabNames.Sort((string a, string b) => Rank(b) - Rank(a));
				HudExt.UpdateHoverIcons(Hud.instance, ItemPrefabNames.ToArray());
			}
		}

		private static int Rank(string itemName)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Expected I4, but got Unknown
			ItemType itemType = ObjectDB.instance.GetItemPrefab(itemName).GetComponent<ItemDrop>().m_itemData.m_shared.m_itemType;
			switch (itemType - 3)
			{
			case 0:
			case 1:
			case 11:
			case 16:
			case 17:
			case 19:
				return 30;
			case 2:
				return 20;
			case 3:
				return 15;
			case 4:
			case 8:
			case 14:
				return 10;
			case 15:
				return 0;
			default:
				return -1;
			}
		}
	}
	[HarmonyPatch(typeof(Beehive))]
	public static class Beehive_HoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		private static void GetHoverText(Beehive __instance, ref string __result)
		{
			IEnumerable<Sprite> source = Enumerable.Repeat<Sprite>(ItemDataExt.GetIcon(__instance.m_honeyItem), __instance.GetHoneyLevel());
			HudExt.UpdateHoverIcons(Hud.instance, source.ToArray());
			if (!__instance.CheckBiome())
			{
				__result += FormatMsg(__instance.m_areaText);
			}
			else if (!__instance.HaveFreeSpace())
			{
				__result += FormatMsg(__instance.m_freespaceText);
			}
			else if (!EnvMan.IsDaylight() && __instance.m_effectOnlyInDaylight)
			{
				__result += FormatMsg(__instance.m_sleepText);
			}
			else
			{
				__result += FormatMsg(__instance.m_happyText);
			}
			static string FormatMsg(string msg)
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				return $"\n\n<color={UIColor.MinorInfo}>{StringExt.Localize(msg)}</color>";
			}
		}
	}
	[HarmonyPatch(typeof(Container))]
	public static class Container_HoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		[HarmonyPriority(300)]
		private static void GetHoverText(Container __instance, ref string __result)
		{
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0280: Unknown result type (might be due to invalid IL or missing references)
			//IL_0247: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.CheckAccess(Player.m_localPlayer.GetPlayerID()))
			{
				int startIndex = __result.IndexOf("\n", StringComparison.Ordinal);
				__result = __result.Remove(startIndex);
				__result += Localization.instance.Localize("\n$piece_noaccess");
				return;
			}
			bool flag = Object.op_Implicit((Object)(object)__instance.m_wagon);
			bool flag2 = !flag && Object.op_Implicit((Object)(object)((Component)__instance).GetComponentInParent<Ship>());
			if ((!WardAccessExt.CanAccessWard((MonoBehaviour)(object)__instance, false) && !flag && !flag2) || !((Object.op_Implicit((Object)(object)__instance.m_piece) && __instance.m_piece.IsPlacedByPlayer()) || flag || flag2))
			{
				return;
			}
			if (__instance.GetInventory().NrOfItems() == 0)
			{
				__result = __result.Replace(StringExt.Localize("( $piece_container_empty )"), "");
				__result += $"\n<color={UIColor.MinorInfo}>$piece_smelter_empty</color>";
				__result = StringExt.Localize(__result);
				return;
			}
			(string, int)[] array = ((Tally<string>)(object)InventoryExt.SumItemsByPrefabName(__instance.GetInventory())).Sorted().ToArray();
			HudExt.UpdateHoverIcons(Hud.instance, array.Select(((string Key, int Amount) sum) => (sum.Key, StringExt.ToHumanString(sum.Amount))).Take(Configs.ContainerMaxIcons.Value).ToArray());
			bool flag3 = !__instance.GetInventory().HaveEmptySlot();
			bool flag4 = flag3 && __instance.GetInventory().GetAllItems().All((ItemData item) => item.m_stack >= item.m_shared.m_maxStackSize);
			string text = (flag4 ? "$msg_itsfull" : null);
			if (array.Length == 1)
			{
				__result += $"\n<color={UIColor.MinorInfo}>{ItemDataExt.GetName(ItemCache.Get(array[0].Item1))}</color>";
			}
			else if (array.Length > 1)
			{
				int num = (Configs.ShowHoverIcons.Value ? Configs.ContainerMaxIcons.Value : 0);
				if (num > 0 && array.Length > num)
				{
					int num2 = array.Length - num;
					string arg = ((num2 == 1) ? "" : "s");
					__result += $"\n<color={UIColor.MinorInfo}>+{num2} More item{arg}...</color>";
				}
				else
				{
					__result += $"\n<color={UIColor.MinorInfo}>{array.Length} Items</color>";
				}
				if (!flag4 && flag3)
				{
					text = "No slots available";
				}
			}
			if (text != null)
			{
				__result += $"<color={UIColor.MinorInfo}> / {text}</color>";
			}
			__result = StringExt.Localize(__result);
		}
	}
	[HarmonyPatch(typeof(CookingStation))]
	public class CookingStation_HoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		internal static void GetHoverText(CookingStation __instance, ref string __result)
		{
			if (Utility.IsNullOrWhiteSpace(__result))
			{
				return;
			}
			List<string> list = new List<string>();
			string text = default(string);
			float num = default(float);
			Status val = default(Status);
			for (int i = 0; i < __instance.m_slots.Length; i++)
			{
				__instance.GetSlot(i, ref text, ref num, ref val);
				if (!Utility.IsNullOrWhiteSpace(text))
				{
					list.Add(text);
				}
			}
			HudExt.UpdateHoverIcons(Hud.instance, list.ToArray());
		}
	}
	[HarmonyPatch(typeof(Fermenter))]
	public static class Fermenter_HoverText
	{
		[HarmonyPrefix]
		[HarmonyPatch("GetHoverText")]
		private static void GetHoverText(Fermenter __instance, ref bool __runOriginal, ref string __result)
		{
			//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_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected I4, but got Unknown
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Unknown result type (might be due to invalid IL or missing references)
			__runOriginal = false;
			if (!WardAccessExt.CanAccessWard((MonoBehaviour)(object)__instance, false))
			{
				__result = Localization.instance.Localize(__instance.m_name + "\n$piece_noaccess");
				return;
			}
			__result = __instance.m_name;
			Status status = __instance.GetStatus();
			switch ((int)status)
			{
			case 0:
				__result += " ( $piece_container_empty )";
				__result = __result + "\n" + UI.PromptInteract + " $piece_fermenter_add";
				break;
			case 1:
				__result += " ( $piece_fermenter_fermenting )";
				break;
			case 3:
				__result += " ( $piece_fermenter_ready )";
				__result = __result + "\n" + UI.PromptInteract + " $piece_fermenter_tap";
				break;
			default:
				__result = __instance.m_name;
				break;
			}
			string contentName = __instance.GetContentName();
			if (!Utility.IsNullOrWhiteSpace(contentName))
			{
				__result += $"\n<color={UIColor.MinorInfo}>{contentName}</color>";
				string content = __instance.GetContent();
				Sprite icon = __instance.GetItemConversion(content).m_from.m_itemData.GetIcon();
				HudExt.UpdateHoverIcons(Hud.instance, (Sprite[])(object)new Sprite[1] { icon });
			}
			if (__instance.m_exposed)
			{
				__result += $"\n<color={UIColor.MajorInfo}>$piece_fermenter_exposed</color>";
			}
			__result = Localization.instance.Localize(__result);
		}
	}
	[HarmonyPatch(typeof(Fireplace))]
	public static class Fireplace_HoverText
	{
		private static Fireplace? _useFireplace;

		[HarmonyPrefix]
		[HarmonyPatch("Interact")]
		private static void Interact_Prefix(Fireplace __instance)
		{
			_useFireplace = __instance;
		}

		[HarmonyPostfix]
		[HarmonyPatch("Interact")]
		private static void Interact_Postfix()
		{
			_useFireplace = null;
		}

		[HarmonyPrefix]
		[HarmonyPatch("UseItem")]
		private static void UseItem_Prefix(Fireplace __instance)
		{
			_useFireplace = __instance;
		}

		[HarmonyPostfix]
		[HarmonyPatch("UseItem")]
		private static void UseItem_Postfix()
		{
			_useFireplace = null;
		}

		[HarmonyTranspiler]
		[HarmonyPatch("Interact")]
		private static IEnumerable<CodeInstruction> Interact_Transpile(IEnumerable<CodeInstruction> codes)
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Mathf), "CeilToInt", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(Fireplace_HoverText), "CalcFuelDays", (Type[])null, (Type[])null);
			return Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)methodInfo2);
		}

		[HarmonyTranspiler]
		[HarmonyPatch("UseItem")]
		private static IEnumerable<CodeInstruction> UseItem_Transpile(IEnumerable<CodeInstruction> codes)
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Mathf), "CeilToInt", (Type[])null, (Type[])null);
			MethodInfo methodInfo2 = AccessTools.Method(typeof(Fireplace_HoverText), "CalcFuelDays", (Type[])null, (Type[])null);
			return Transpilers.MethodReplacer(codes, (MethodBase)methodInfo, (MethodBase)methodInfo2);
		}

		[HarmonyTranspiler]
		[HarmonyPatch("RPC_AddFuel")]
		private static IEnumerable<CodeInstruction> RPC_AddFuel_Transpile(IEnumerable<CodeInstruction> codes)
		{
			MethodInfo ceilToInt = AccessTools.Method(typeof(Mathf), "CeilToInt", (Type[])null, (Type[])null);
			return Transpilers.Manipulator(codes, (Func<CodeInstruction, bool>)((CodeInstruction ci) => CodeInstructionExtensions.Calls(ci, ceilToInt)), (Action<CodeInstruction>)delegate(CodeInstruction ci)
			{
				ci.opcode = OpCodes.Nop;
				ci.operand = null;
			});
		}

		private static float CalcFuelDays(float fuel)
		{
			if (!Object.op_Implicit((Object)(object)_useFireplace))
			{
				Log.Warning((object)"_useFireplace is missing, can not check remaining fueldays.  Returning CeilToInt instead.Did a mod break Fireplace.UseItem or Fireplace.Interact on Prefix/Postfix?", (ushort)0);
				return Mathf.CeilToInt(fuel);
			}
			if (FireplaceExt.IsFuelDaysEmpty(_useFireplace, (float?)null))
			{
				return Mathf.Ceil(fuel);
			}
			return fuel;
		}

		[HarmonyPrefix]
		[HarmonyPatch("GetHoverText")]
		private static void GetHoverText(Fireplace __instance, ref bool __runOriginal, ref string __result)
		{
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.m_infiniteFuel && __instance.m_nview.IsValid())
			{
				ItemData itemData = __instance.m_fuelItem.m_itemData;
				if (Configs.ShowHoverIconForFuel.Value)
				{
					HudExt.UpdateHoverIcons(Hud.instance, (Sprite[])(object)new Sprite[1] { itemData.GetIcon() });
				}
				__runOriginal = false;
				float @float = __instance.m_nview.GetZDO().GetFloat(ZDOVars.s_fuel, 0f);
				string arg = UI.RemainingTimeText(@float * __instance.m_secPerFuel, __instance.m_secPerFuel);
				bool flag = __instance.m_fireworkItemList.Length != 0 && ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItems().Any((ItemData item) => ItemDataExt.GetName(item).StartsWith("$item_fireworkrocket"));
				string text = string.Empty;
				if (__instance.m_canRefill)
				{
					text = "\n" + UI.PromptInteract + " $piece_use " + ItemDataExt.GetName(itemData) + (flag ? ("\n" + UI.PromptUseItem + " $piece_useitem") : string.Empty);
				}
				else if (__instance.m_canTurnOff && @float > 0f)
				{
					text = "\n" + UI.PromptInteract + " $piece_use";
				}
				string text2 = __instance.m_name + text + $"\n<color={UIColor.MinorInfo}>Fuel remaining: {arg}</color>";
				__result = Localization.instance.Localize(text2);
			}
		}
	}
	[HarmonyPatch(typeof(ItemDrop))]
	public static class ItemDrop_HoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		[HarmonyPriority(200)]
		private static void GetHoverText(ItemDrop __instance, ref string __result)
		{
			__result += __instance.m_itemData.GetHoverDescription();
			HudExt.UpdateHoverIcons(Hud.instance, (Sprite[])(object)new Sprite[1] { ItemDataExt.GetIcon(__instance) });
		}
	}
	[HarmonyPatch(typeof(ItemStand))]
	public static class ItemStand_HoverText
	{
		private static bool IsValid(ItemStand itemStand)
		{
			if (!itemStand.HaveAttachment() || !ItemStandExt.CanBeRemoved(itemStand) || ItemStandExt.IsBossStone(itemStand))
			{
				return false;
			}
			if (Utility.IsNullOrWhiteSpace(itemStand.m_visualName))
			{
				return false;
			}
			return true;
		}

		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		[HarmonyPriority(300)]
		private static void GetHoverText(ItemStand __instance, ref string __result)
		{
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			if (IsValid(__instance))
			{
				Sprite icon = ItemDataExt.GetIcon(ItemCache.Get(__instance.m_visualName), __instance.m_visualVariant);
				HudExt.UpdateHoverIcons(Hud.instance, (Sprite[])(object)new Sprite[1] { icon });
				int startIndex = __result.IndexOf("\n", StringComparison.Ordinal);
				__result = __instance.GetHoverName() + __result.Substring(startIndex);
				__result += $"\n<color={UIColor.MinorInfo}>{__instance.m_currentItemName}</color>";
				__result = Localization.instance.Localize(__result);
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		[HarmonyPriority(200)]
		private static void GetHoverText_ItemDescription(ItemStand __instance, ref string __result)
		{
			if (IsValid(__instance))
			{
				ItemDrop val = ItemCache.Get(__instance.m_visualName);
				__result += val.m_itemData.GetHoverDescription();
			}
		}
	}
	[HarmonyPatch]
	public static class Oven_HoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Switch), "GetHoverText")]
		[HarmonyPriority(0)]
		internal static void GetHoverText(Switch __instance, ref string __result)
		{
			CookingStation componentInParent = ((Component)__instance).GetComponentInParent<CookingStation>();
			if (Object.op_Implicit((Object)(object)componentInParent))
			{
				CookingStation_HoverText.GetHoverText(componentInParent, ref __result);
			}
		}
	}
	[HarmonyPatch(typeof(Pickable))]
	public static class Pickable_HoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		[HarmonyPriority(200)]
		private static void GetHoverText(Pickable __instance, ref string __result)
		{
			if (!__instance.m_picked)
			{
				ItemDrop val = ItemCache.Get(((Object)__instance.m_itemPrefab).name);
				__result += val.m_itemData.GetHoverDescription();
				HudExt.UpdateHoverIcons(Hud.instance, (Sprite[])(object)new Sprite[1] { ItemDataExt.GetIcon(val) });
			}
		}
	}
	[HarmonyPatch(typeof(PickableItem))]
	public static class PickableItem_HoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		[HarmonyPriority(200)]
		private static void GetHoverText(PickableItem __instance, ref string __result)
		{
			if (!__instance.m_picked && Object.op_Implicit((Object)(object)__instance.m_itemPrefab))
			{
				__result += __instance.m_itemPrefab.m_itemData.GetHoverDescription();
				HudExt.UpdateHoverIcons(Hud.instance, (Sprite[])(object)new Sprite[1] { ItemDataExt.GetIcon(__instance.m_itemPrefab) });
			}
		}
	}
	[HarmonyPatch(typeof(SapCollector))]
	public class SapCollector_HoverText
	{
		[HarmonyPrefix]
		[HarmonyPatch("GetHoverText")]
		private static void GetHoverText(SapCollector __instance, ref bool __runOriginal, ref string __result)
		{
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			ItemData itemData = __instance.m_spawnItem.m_itemData;
			int level = __instance.GetLevel();
			HudExt.UpdateHoverIcons(Hud.instance, (Sprite[])(object)new Sprite[1] { itemData.GetIcon() });
			__runOriginal = false;
			string text = $"{__instance.m_name} ({level}/{__instance.m_maxLevel})" + "\n" + UI.PromptInteract + " " + __instance.m_extractText + $"\n<color={UIColor.MinorInfo}>{__instance.GetStatusText()}</color>";
			__result = Localization.instance.Localize(text);
		}
	}
	[HarmonyPatch(typeof(Smelter))]
	internal static class Smelter_HoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch("OnHoverEmptyOre")]
		private static void GetHoverText_EmptyOre(Smelter __instance, ref string __result)
		{
			ItemConversion itemConversion = __instance.GetItemConversion(__instance.GetQueuedOre());
			if (itemConversion != null)
			{
				ItemData itemData = itemConversion.m_to.m_itemData;
				HudExt.UpdateHoverIcons(Hud.instance, (Sprite[])(object)new Sprite[1] { itemData.GetIcon() });
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnHoverAddFuel")]
		private static void GetHoverText_AddFuel(Smelter __instance, ref string __result)
		{
			int num = Mathf.CeilToInt(__instance.GetFuel());
			ItemData itemData = __instance.m_fuelItem.m_itemData;
			string text = ((num < __instance.m_maxFuel) ? (UI.PromptInteract + " $piece_smelter_add " + ItemDataExt.GetName(itemData)) : "$msg_itsfull");
			string text2 = $"{__instance.m_name} ({ItemDataExt.GetName(itemData)} {num}/{__instance.m_maxFuel})\n{text}";
			__result = Localization.instance.Localize(text2);
			if (Configs.ShowHoverIconForFuel.Value)
			{
				HudExt.UpdateHoverIcons(Hud.instance, (Sprite[])(object)new Sprite[1] { itemData.GetIcon() });
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnHoverAddOre")]
		private static void GetHoverText_AddOre(Smelter __instance, ref string __result)
		{
			//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			List<string> rawQueue = new List<string>();
			for (int i = 0; i < __instance.GetQueueSize(); i++)
			{
				string @string = __instance.m_nview.GetZDO().GetString("item" + i, "");
				rawQueue.Add(@string);
			}
			List<(string, string)> list = (from ore in rawQueue.Select((string name, int index) => (name, index))
				group ore by (ore.PrefabName, rawQueue.Take(ore.Index).Count((string name) => name != ore.PrefabName)) into @group
				select (@group.Key.PrefabName, StringExt.ToHumanString(@group.Count()))).ToList();
			HudExt.UpdateHoverIcons(Hud.instance, list.ToArray());
			string text = string.Empty;
			foreach (var item in list)
			{
				ItemDrop val = ItemCache.Get(item.Item1);
				text += $"\n-   <color={UIColor.MinorInfo}>{ItemDataExt.GetName(val)}</color>";
			}
			if (__instance.m_requiresRoof && !__instance.m_haveRoof)
			{
				text += $"\n<color={UIColor.MajorInfo}>$piece_smelter_reqroof</color>";
				__result = __result.Replace(StringExt.Localize(" <color=yellow>$piece_smelter_reqroof</color>"), string.Empty);
			}
			__result += Localization.instance.Localize(text);
		}
	}
	[HarmonyPatch(typeof(WispSpawner))]
	public static class WispSpawner_HoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		private static void GetHoverText(WispSpawner __instance, ref string __result)
		{
			int startIndex = __result.IndexOf("(", StringComparison.Ordinal);
			__result = __result.Insert(startIndex, "\n");
		}
	}
}