Decompiled source of ZenHoverItem v0.4.12

plugins/ZenHoverItem.dll

Decompiled 16 hours 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 System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using Zen;
using Zen.Lib;
using Zen.Lib.Config;

[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
{
	[Flags]
	public enum FuelPieceType
	{
		None = 0,
		Fireplace = 1,
		SmelterFuel = 2,
		SmelterOre = 4
	}
	internal static class Configs
	{
		public static readonly ConfigEntry<bool> ShowHoverIcons;

		public static readonly ConfigEntry<FuelPieceType> ShowHoverIconForFuel;

		public static readonly ConfigEntry<FuelPieceType> ShowFuelMeter;

		public static readonly ConfigEntry<FuelPieceType> ShowFuelCapacity;

		public static readonly ConfigEntry<bool> AdjustFuelBurnRate;

		public static readonly ConfigEntry<bool> ShowFuelDays;

		public static readonly ConfigEntry<bool> ShowSmelterQueue;

		public static readonly ConfigEntry<bool> ReformatHoverText;

		public static readonly ConfigEntry<int> ContainerMaxIcons;

		public static readonly ConfigEntry<bool> ContainerShowSummaryText;

		public static readonly ConfigEntry<bool> ContainerShowHoldToStack;

		public static readonly ConfigEntry<bool> ArmorStandShowHoverIcons;

		public static readonly ConfigEntry<bool> ArmorStandShowHoverText;

		public static readonly ConfigEntry<bool> ShowItemDescription;

		public static readonly ConfigEntry<bool> ShowShieldGenMeter;

		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<FuelPieceType>(true, "Fuel", "Show Icon", FuelPieceType.Fireplace | FuelPieceType.SmelterFuel | FuelPieceType.SmelterOre, "Show the hover icon for fuelable things such as fireplaces, torches, and smelters");
			ShowFuelCapacity = Config.Define<FuelPieceType>(true, "Fuel", "Show Capacity", FuelPieceType.Fireplace | FuelPieceType.SmelterFuel, "Show the capacity x/max for fuelable things such as fireplaces, torches, and smelters");
			ShowFuelMeter = Config.Define<FuelPieceType>(true, "Fuel", "Show Meter", FuelPieceType.SmelterFuel | FuelPieceType.SmelterOre, "Show the fuel meter");
			ShowSmelterQueue = Config.Define<bool>(true, "Fuel", "Show Smelter Queue", true, "Show the queue on smelters");
			ShowFuelDays = Config.Define<bool>(true, "Fuel", "Display Fuel Days", true, "Show the number of game days of fuel remaining on Fireplaces. (Vanilla: false)\r\nThis helps you understand the different dynamics of the various light sources and realize they are not just cosmetic.\r\nThe game itself does not provide a clock. Vikings had no clocks. The only unit of time they had was days.\r\nInstall ZenCompass to see the passage of time.\r\nNOTE: This is very important when using ZenRaids as you need to know how long before the fire burns out and monsters spawn.\r\nAlso, in a mod like Seasons you need to know if you have enough fuel to last the winter.");
			AdjustFuelBurnRate = Config.Define<bool>(true, "Fuel", "Adjust Fuel Burn Rate", true, "This will adjust the fuel burn rate on fireplaces so the amount of days remaining when full are easily recognizable numbers. (Vanilla: false)\r\nVanilla day lengths and fuel burn times are not evenly divisible resulting in awkward max fuel days.\r\nThis adjusts the burn rate per unit of fuel so they divide evenly with the day length.\r\nThe result is that max fuel days will be easily recognizable days 20, 25, 50, 60 instead of 22, 28, 56, 67.\r\n[logout required for changes to take effect]");
			ContainerMaxIcons = Config.Define<int>(true, "Containers", "Container Max Icons", 4, Config.AcceptRange<int>(0, 5), "How many icons to display on containers?");
			ContainerShowSummaryText = Config.Define<bool>(true, "Containers", "Show Summary Text", true, "Show the summary text for containers");
			ContainerShowHoldToStack = Config.Define<bool>(true, "Containers", "Show Hold To Stack", true, "Show the phrase \"Hold to stack\" on the tooltip for containers (vanilla: true)");
			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");
			ShowShieldGenMeter = Config.Define<bool>(true, "Shield Generator", "Show Shield Meter", true, "Display the power of the shield as a meter when looking at the generator");
			ReformatHoverText = Config.Define<bool>(true, "Plants / Crops", "Reformat HoverText", true, "Reformat the hover text for crops to make it look nicer (vanilla: false)");
		}
	}
	internal static class Extensions
	{
		internal static string CreateMeter(this Fireplace fireplace, float fuel)
		{
			return UI.CreateMeter(fuel, fireplace.m_maxFuel, 10);
		}

		internal static string CreateMeterOre(this Smelter smelter, float oreCount)
		{
			return UI.CreateMeter(oreCount, (float)smelter.m_maxOre, 10);
		}

		internal static string CreateMeterFuel(this Smelter smelter, float fuel)
		{
			return UI.CreateMeter(fuel, (float)smelter.m_maxFuel, 10);
		}

		internal static string CreateMeter(this ShieldGenerator shieldGen)
		{
			return UI.CreateMeter(shieldGen.GetFuel(), (float)shieldGen.m_maxFuel, 10);
		}

		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>";
		}
	}
	internal 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_00fb: Unknown result type (might be due to invalid IL or missing references)
				//IL_012f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0135: 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);
				((Graphic)Icon).material = Materials.IconCleanTransparency;
				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.3f);
				((Behaviour)component).enabled = true;
				((Component)obj).gameObject.SetActive(false);
				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);
					}
				}
			}
		}

		public 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;

		public 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));
			}
		}

		public 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, string.Empty)));
		}

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

		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 != string.Empty;
					_elements[index].Label.text = label;
				}
				_isDirty = true;
			}
		}
	}
	internal static class ItemCache
	{
		private static readonly Dictionary<string, ItemDrop> PrefabCache = new Dictionary<string, ItemDrop>();

		public static ItemDrop Get(string prefabName)
		{
			//IL_004e: 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_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			prefabName = Utils.GetPrefabName(prefabName);
			if (PrefabCache.TryGetValue(prefabName, out ItemDrop value))
			{
				return value;
			}
			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 val = obj;
			return PrefabCache[prefabName] = val;
		}
	}
	[BepInPlugin("ZenDragon.ZenHoverItem", "ZenHoverItem", "0.4.12")]
	[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.4.12";

		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]
	internal static class ArmorStandHoverText
	{
		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))]
	internal static class BeehiveHoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		private static void GetHoverText(Beehive __instance, ref string __result)
		{
			Sprite icon = ItemDataExt.GetIcon(__instance.m_honeyItem);
			int honeyLevel = __instance.GetHoneyLevel();
			int maxHoney = __instance.m_maxHoney;
			if (honeyLevel > 5 || maxHoney > 5)
			{
				HudExt.UpdateHoverIcons(Hud.instance, new(Sprite, string)[1] { (icon, $"{honeyLevel}/{maxHoney}") });
			}
			else
			{
				HudExt.UpdateHoverIcons(Hud.instance, Enumerable.Repeat<Sprite>(icon, honeyLevel).ToArray());
			}
			__result = StringExt.Localize(__instance.m_name + "\n" + UI.PromptInteract + " $piece_beehive_extract");
			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 StringExt.Localize($"\n\n<color={UIColor.MinorInfo}>{msg}</color>");
			}
		}
	}
	[HarmonyPatch(typeof(Container))]
	internal static class ContainerHoverText
	{
		public static (string Key, int Amount)[] UpdateHoverIcons(this Container container)
		{
			(string, int)[] array = ((Tally<string>)(object)InventoryExt.SumItemsByPrefabName(container.GetInventory())).Sorted().ToArray();
			bool isAll1 = array.All(((string Key, int Amount) sum) => sum.Amount == 1);
			HudExt.UpdateHoverIcons(Hud.instance, array.Select(((string Key, int Amount) sum) => (sum.Key, isAll1 ? string.Empty : StringExt.ToHumanString(sum.Amount))).Take(Configs.ContainerMaxIcons.Value).ToArray());
			return array;
		}

		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		[HarmonyPriority(300)]
		private static void GetHoverText(Container __instance, ref string __result)
		{
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.CheckAccess(Player.m_localPlayer.GetPlayerID()))
			{
				int startIndex = __result.IndexOf("\n", StringComparison.Ordinal);
				__result = __result.Remove(startIndex);
				__result += StringExt.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(__instance, false) && !flag && !flag2) || !((Object.op_Implicit((Object)(object)__instance.m_piece) && __instance.m_piece.IsPlacedByPlayer()) || flag || flag2))
			{
				return;
			}
			if (!Configs.ContainerShowHoldToStack.Value)
			{
				__result = __result.Replace(StringExt.Localize(" $msg_stackall_hover"), string.Empty);
			}
			if (__instance.GetInventory().NrOfItems() == 0)
			{
				__result = __result.Replace(StringExt.Localize("( $piece_container_empty )"), string.Empty);
				__result += $"\n<color={UIColor.MinorInfo}>$piece_smelter_empty</color>";
				__result = StringExt.Localize(__result);
				return;
			}
			(string, int)[] array = __instance.UpdateHoverIcons();
			if (!Configs.ContainerShowSummaryText.Value)
			{
				return;
			}
			string text = ((!__instance.GetInventory().HaveEmptySlot() && __instance.GetInventory().GetAllItems().All((ItemData item) => item.m_stack >= item.m_shared.m_maxStackSize)) ? "$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) ? "$hover_container_items_more_1" : StringExt.Localize("$hover_container_items_more_N", new string[1] { num2.ToString() }));
					__result += $"\n<color={UIColor.MinorInfo}>{arg}</color>";
				}
				else
				{
					__result += StringExt.Localize($"\n<color={UIColor.MinorInfo}>$hover_container_items_count</color>", new string[1] { array.Length.ToString() });
				}
			}
			if (text != null)
			{
				__result += $"<color={UIColor.MinorInfo}> / {text}</color>";
			}
			__result = StringExt.Localize(__result);
		}
	}
	[HarmonyPatch(typeof(CookingStation))]
	internal class CookingStationHoverText
	{
		[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]
	internal static class CraftingStationHoverText
	{
		private static void HandleContainerMods(CraftingStation station, ref string result)
		{
			Container val = default(Container);
			if (((Component)station).TryGetComponent<Container>(ref val) && val.GetInventory() != null)
			{
				if (station.InUseDistance((Humanoid)(object)Player.m_localPlayer))
				{
					result = val.GetHoverText();
				}
				else
				{
					val.UpdateHoverIcons();
				}
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch(typeof(CraftingStation), "GetHoverText")]
		private static void CraftingStation_GetHoverText(CraftingStation __instance, ref string __result)
		{
			HandleContainerMods(__instance, ref __result);
		}
	}
	[HarmonyPatch]
	internal static class FeastHoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Feast), "GetHoverText")]
		private static void Feast_GetHoverText(Feast __instance, ref string __result)
		{
			if (!Configs.ShowHoverIcons.Value)
			{
				return;
			}
			if (Object.op_Implicit((Object)(object)__instance.m_foodItem))
			{
				string item = $"{__instance.GetStack()}/{__instance.m_eatStacks}";
				Sprite icon = ItemDataExt.GetIcon(__instance.m_foodItem);
				HudExt.UpdateHoverIcons(Hud.instance, new(Sprite, string)[1] { (icon, item) });
			}
			if (!Utility.IsNullOrWhiteSpace(__result))
			{
				int num = __result.IndexOf("(", StringComparison.Ordinal);
				if (num >= 0)
				{
					__result = __result.Substring(0, num);
				}
			}
		}
	}
	[HarmonyPatch(typeof(Fermenter))]
	internal static class FermenterHoverText
	{
		[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))]
	internal static class FireplaceHoverText
	{
		private static readonly Dictionary<string, float> SecPerFuelDefaultsCache = new Dictionary<string, float>();

		private static Fireplace? _useFireplace;

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Game), "Start")]
		private static void Game_Start()
		{
			Logging<Plugin>.Info((object)"Clear the fuel burn rate cache", 0);
			SecPerFuelDefaultsCache.Clear();
		}

		[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;
		}

		[HarmonyPrefix]
		[HarmonyPatch("UpdateFireplace")]
		private static void UpdateFireplace(Fireplace __instance)
		{
			if (Configs.AdjustFuelBurnRate.Value)
			{
				if (!SecPerFuelDefaultsCache.TryGetValue(__instance.m_nview.GetPrefabName(), out var value))
				{
					string prefabName = __instance.m_nview.GetPrefabName();
					value = ZNetScene.instance.GetPrefab(prefabName).GetComponent<Fireplace>().m_secPerFuel;
					SecPerFuelDefaultsCache.Add(prefabName, value);
				}
				__instance.m_secPerFuel = value * (float)EnvMan.instance.m_dayLengthSec / 2000f;
			}
		}

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

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

		[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 CalcFuelLimit(float fuel)
		{
			if ((Object)(object)_useFireplace == (Object)null)
			{
				Logging<Plugin>.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?", 0);
				return Mathf.CeilToInt(fuel);
			}
			if (FireplaceExt.IsFuelDaysEmpty(_useFireplace, (float?)null) || FireplaceExt.IsFuelDaysFull(_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_01b8: Unknown result type (might be due to invalid IL or missing references)
			if (!__instance.m_infiniteFuel && __instance.m_nview.IsValid())
			{
				__runOriginal = false;
				ItemData itemData = __instance.m_fuelItem.m_itemData;
				float num = default(float);
				string arg = UI.RemainingTimeText(FireplaceExt.FuelTimeRemaining(__instance, ref num), __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;
				bool flag2 = Configs.ShowFuelCapacity.Value.HasFlag(FuelPieceType.Fireplace);
				bool flag3 = Configs.ShowHoverIconForFuel.Value.HasFlag(FuelPieceType.Fireplace);
				bool flag4 = Configs.ShowFuelMeter.Value.HasFlag(FuelPieceType.Fireplace);
				if (__instance.m_canRefill)
				{
					text = ((flag2 && !flag3) ? $" ({Mathf.Ceil(num)}/{__instance.m_maxFuel})" : string.Empty) + "\n" + UI.PromptInteract + " $piece_use " + ItemDataExt.GetName(itemData) + (flag ? ("\n" + UI.PromptUseItem + " $piece_useitem") : string.Empty);
				}
				else if (__instance.m_canTurnOff && num > 0f)
				{
					text = "\n" + UI.PromptInteract + " $piece_use";
				}
				string text2 = (flag4 ? __instance.CreateMeter(num) : string.Empty);
				string text3 = (Configs.ShowFuelDays.Value ? $"\n<color={UIColor.MinorInfo}>$hover_fireplace_fuel_remaining {arg}</color>" : string.Empty);
				string text4 = __instance.m_name + text + text3 + text2;
				__result = Localization.instance.Localize(text4);
				if (flag3 && num > 0f)
				{
					string item2 = ((__instance.m_infiniteFuel || !flag2) ? string.Empty : $"{Mathf.CeilToInt(num)}/{__instance.m_maxFuel}");
					HudExt.UpdateHoverIcons(Hud.instance, new(Sprite, string)[1] { (itemData.GetIcon(), item2) });
				}
			}
		}
	}
	[HarmonyPatch(typeof(ItemDrop))]
	internal static class ItemDropHoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		[HarmonyPriority(200)]
		private static void GetHoverText(ItemDrop __instance, ref string __result)
		{
			__result = Regex.Replace(__result, "\\sx\\d+$", string.Empty, RegexOptions.Multiline);
			__result += __instance.m_itemData.GetHoverDescription();
			int stack = __instance.m_itemData.m_stack;
			if (stack > 1)
			{
				HudExt.UpdateHoverIcons(Hud.instance, new(Sprite, string)[1] { (ItemDataExt.GetIcon(__instance), StringExt.ToHumanString(stack)) });
			}
			else
			{
				HudExt.UpdateHoverIcons(Hud.instance, (Sprite[])(object)new Sprite[1] { ItemDataExt.GetIcon(__instance) });
			}
		}
	}
	[HarmonyPatch(typeof(ItemStand))]
	internal static class ItemStandHoverText
	{
		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;
		}

		internal static Sprite? GetAttachedItemIcon(this ItemStand itemStand)
		{
			if (!IsValid(itemStand))
			{
				return null;
			}
			return ItemDataExt.GetIcon(ItemCache.Get(itemStand.m_visualName), itemStand.m_visualVariant);
		}

		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		[HarmonyPriority(300)]
		private static void GetHoverText(ItemStand __instance, ref string __result)
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			Sprite attachedItemIcon = __instance.GetAttachedItemIcon();
			if (Object.op_Implicit((Object)(object)attachedItemIcon))
			{
				HudExt.UpdateHoverIcons(Hud.instance, (Sprite[])(object)new Sprite[1] { attachedItemIcon });
				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]
	internal static class OvenHoverText
	{
		private const string OvenPrefabName = "piece_oven";

		[HarmonyPostfix]
		[HarmonyPatch(typeof(Switch), "GetHoverText")]
		[HarmonyPriority(0)]
		internal static void GetHoverText(Switch __instance, ref string __result)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Expected O, but got Unknown
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Expected O, but got Unknown
			object? target = ((Delegate)(object)__instance.m_onUse).Target;
			CookingStation val = (CookingStation)((target is CookingStation) ? target : null);
			if (val == null || GameObjectExt.GetPrefabName(((Component)val).gameObject) != "piece_oven")
			{
				return;
			}
			if ((Delegate?)(object)__instance.m_onUse == (Delegate?)new Callback(val.OnAddFoodSwitch))
			{
				CookingStationHoverText.GetHoverText(val, ref __result);
			}
			if ((Delegate?)(object)__instance.m_onUse == (Delegate?)new Callback(val.OnAddFuelSwitch))
			{
				bool flag = Configs.ShowFuelCapacity.Value.HasFlag(FuelPieceType.Fireplace);
				bool flag2 = Configs.ShowHoverIconForFuel.Value.HasFlag(FuelPieceType.Fireplace);
				bool num = Configs.ShowFuelMeter.Value.HasFlag(FuelPieceType.Fireplace);
				Sprite icon = ItemDataExt.GetIcon(val.m_fuelItem);
				int num2 = Mathf.CeilToInt(val.GetFuel());
				int maxFuel = val.m_maxFuel;
				string text = (num ? UI.CreateMeter((float)num2, (float)maxFuel, 10) : string.Empty);
				string text2 = $"{num2}/{maxFuel}";
				if (flag2)
				{
					HudExt.UpdateHoverIcons(Hud.instance, new(Sprite, string)[1] { (icon, flag ? text2 : string.Empty) });
				}
				__result = StringExt.Localize(val.m_name + " " + ((flag && !flag2) ? ("(" + text2 + ")") : string.Empty) + "\n" + UI.PromptInteract + " $piece_smelter_add " + ItemDataExt.GetName(val.m_fuelItem) + text);
			}
		}
	}
	[HarmonyPatch]
	internal static class PetHoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Pet), "GetHoverText")]
		private static void Pet_GetHoverText(Pet __instance)
		{
			if (Object.op_Implicit((Object)(object)__instance.m_itemStand))
			{
				Sprite attachedItemIcon = __instance.m_itemStand.GetAttachedItemIcon();
				if (__instance.m_nview.GetPrefabName() == "Placeable_HardRock")
				{
					Sprite icon = ItemDataExt.GetIcon(ItemCache.Get("StoneRock"));
					HudExt.UpdateHoverIcons(Hud.instance, (Sprite[])(object)((!Object.op_Implicit((Object)(object)attachedItemIcon)) ? new Sprite[1] { icon } : new Sprite[2] { icon, attachedItemIcon }));
				}
				else if (Object.op_Implicit((Object)(object)attachedItemIcon))
				{
					HudExt.UpdateHoverIcons(Hud.instance, (Sprite[])(object)new Sprite[1] { attachedItemIcon });
				}
			}
		}
	}
	[HarmonyPatch(typeof(Pickable))]
	internal static class PickableHoverText
	{
		[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))]
	internal static class PickableItemHoverText
	{
		[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]
	internal static class PlantsHoverText
	{
		[HarmonyPrefix]
		[HarmonyPatch(typeof(Plant), "GetHoverText")]
		private static void Planet_GetHoverText(Plant __instance, ref string __result, ref bool __runOriginal)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: 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_001a: 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_0033: Unknown result type (might be due to invalid IL or missing references)
			if (Configs.ReformatHoverText.Value)
			{
				__runOriginal = false;
				Status status = __instance.GetStatus();
				ZColor val = (((int)status == 0) ? UIColor.MinorInfo : UIColor.Orange);
				__result = StringExt.Localize($"{__instance.m_name}\n<color={val}>$piece_plant_{((object)(Status)(ref status)).ToString().ToLower()}</color>");
			}
		}
	}
	[HarmonyPatch(typeof(SapCollector))]
	internal class SapCollectorHoverText
	{
		[HarmonyPrefix]
		[HarmonyPatch("GetHoverText")]
		private static void GetHoverText(SapCollector __instance, ref bool __runOriginal, ref string __result)
		{
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			__runOriginal = false;
			Sprite icon = __instance.m_spawnItem.m_itemData.GetIcon();
			int level = __instance.GetLevel();
			int maxLevel = __instance.m_maxLevel;
			if (level > 5 || maxLevel > 5)
			{
				HudExt.UpdateHoverIcons(Hud.instance, new(Sprite, string)[1] { (icon, $"{level}/{maxLevel}") });
			}
			else
			{
				HudExt.UpdateHoverIcons(Hud.instance, Enumerable.Repeat<Sprite>(icon, level).ToArray());
			}
			string text = UI.CreateMeter((float)level, (float)maxLevel, 10);
			string text2 = __instance.m_name + "\n" + UI.PromptInteract + " " + __instance.m_extractText + $"\n<color={UIColor.MinorInfo}>{__instance.GetStatusText()}</color>" + text;
			__result = StringExt.Localize(text2);
		}
	}
	[HarmonyPatch]
	internal static class ShieldGenHoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(Switch), "GetHoverText")]
		[HarmonyPriority(100)]
		private static void Switch_ShieldGenerator_GetHoverText(Switch __instance, ref string __result)
		{
			ShieldGenerator componentInParent = ((Component)__instance).GetComponentInParent<ShieldGenerator>();
			if (Object.op_Implicit((Object)(object)componentInParent) && Configs.ShowShieldGenMeter.Value)
			{
				__result = Regex.Replace(__result, " \\(.+?\\)$", string.Empty, RegexOptions.Multiline);
				__result += componentInParent.CreateMeter();
			}
		}
	}
	[HarmonyPatch(typeof(Smelter))]
	internal static class SmelterHoverText
	{
		[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, new(Sprite, string)[1] { (itemData.GetIcon(), __instance.GetProcessedQueueSize().ToString()) });
				__result = Regex.Replace(__result, "\\(.+?\\)", string.Empty, RegexOptions.Multiline);
			}
		}

		[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 = "\n" + UI.PromptInteract + " $piece_smelter_add " + ItemDataExt.GetName(itemData);
			string text2 = (Configs.ShowFuelMeter.Value.HasFlag(FuelPieceType.SmelterFuel) ? __instance.CreateMeterFuel(num) : string.Empty);
			bool flag = Configs.ShowFuelCapacity.Value.HasFlag(FuelPieceType.SmelterFuel);
			bool num2 = Configs.ShowHoverIconForFuel.Value.HasFlag(FuelPieceType.SmelterFuel);
			string text3 = string.Concat(str1: (num2 || !flag) ? string.Empty : $" ({num}/{__instance.m_maxFuel})", str0: __instance.m_name, str2: text, str3: text2);
			__result = Localization.instance.Localize(text3);
			if (num2 && num > 0)
			{
				string item = (flag ? $"{num}/{__instance.m_maxFuel}" : string.Empty);
				HudExt.UpdateHoverIcons(Hud.instance, new(Sprite, string)[1] { (itemData.GetIcon(), item) });
			}
		}

		[HarmonyPostfix]
		[HarmonyPatch("OnHoverAddOre")]
		[HarmonyPriority(100)]
		private static void GetHoverText_AddOre(Smelter __instance, ref string __result)
		{
			//IL_01c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			List<string> rawQueue = new List<string>();
			int queueSize = __instance.GetQueueSize();
			for (int i = 0; i < queueSize; 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();
			if (Configs.ShowHoverIconForFuel.Value.HasFlag(FuelPieceType.SmelterOre))
			{
				HudExt.UpdateHoverIcons(Hud.instance, list.ToArray());
			}
			string text = string.Empty;
			if (!Configs.ShowFuelCapacity.Value.HasFlag(FuelPieceType.SmelterOre))
			{
				__result = Regex.Replace(__result, "\\(.+?\\)", string.Empty, RegexOptions.Multiline);
			}
			if (Configs.ShowFuelMeter.Value.HasFlag(FuelPieceType.SmelterOre))
			{
				text += __instance.CreateMeterOre(queueSize);
			}
			if (Configs.ShowSmelterQueue.Value)
			{
				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]
	internal static class TombStoneHoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(TombStone), "GetHoverText")]
		private static void TombStone_GetHoverText(TombStone __instance, ref string __result)
		{
			HudExt.UpdateHoverIcons(Hud.instance, (Sprite[])(object)new Sprite[1] { Minimap.instance.GetSprite((PinType)4) });
		}
	}
	[HarmonyPatch(typeof(WispSpawner))]
	internal static class WispSpawnerHoverText
	{
		[HarmonyPostfix]
		[HarmonyPatch("GetHoverText")]
		private static void GetHoverText(WispSpawner __instance, ref string __result)
		{
			int startIndex = __result.IndexOf("(", StringComparison.Ordinal);
			__result = __result.Insert(startIndex, "\n");
		}
	}
}