Decompiled source of MarsarahUI v1.1.0

MarsarahUI.dll

Decompiled 2 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using HarmonyLib;
using JetBrains.Annotations;
using MarsarahUI.Managers;
using MarsarahUI.Patches.UI;
using Microsoft.CodeAnalysis;
using ServerSync;
using TMPro;
using UnityEngine;
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("MarsarahUI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MarsarahUI")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("7138bb38-6a11-44f4-8009-836df083e4de")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace MarsarahUI
{
	[BepInPlugin("Marsarah.MarsarahUI", "MarsarahUI", "1.1.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class MarsarahUI : BaseUnityPlugin
	{
		internal const string ModName = "MarsarahUI";

		internal const string ModVersion = "1.1.0";

		internal const string Author = "Marsarah";

		public const string ModGUID = "Marsarah.MarsarahUI";

		private readonly Harmony harmony = new Harmony("Marsarah.MarsarahUI");

		private static readonly LogManager log = new LogManager("Main", LogManager.LogLevel.Warning);

		private void Awake()
		{
			LogManager.SetGlobalLogLevel(LogManager.LogLevel.Warning);
			ConfigManager.Init(((BaseUnityPlugin)this).Config);
			harmony.PatchAll();
			log.Info("MarsarahUI v1.1.0 loaded.");
		}

		private void Start()
		{
			CompatibilityManager.Initialize();
		}

		private void Update()
		{
			UIController.UpdateUIDisplay();
		}

		private void OnDestroy()
		{
			((BaseUnityPlugin)this).Config.Save();
		}
	}
}
namespace MarsarahUI.Patches.UI
{
	internal class UIAshlandsHeatLevel : UIController
	{
		[HarmonyPatch(typeof(Hud), "Awake")]
		private static class HeatLevel_HUDAwakePatch
		{
			private static void Postfix(Hud __instance)
			{
				if ((!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsDedicated()) && !((Object)(object)__instance == (Object)null) && ConfigManager.EffectiveShowHeatLevelInAshlands)
				{
					CreateUI(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Hud), "Update")]
		private static class HeatLevel_HUDUpdatePatch
		{
			private static void Postfix(Hud __instance)
			{
				//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
				//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
				//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_01da: Unknown result type (might be due to invalid IL or missing references)
				//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
				//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
				//IL_0204: Unknown result type (might be due to invalid IL or missing references)
				//IL_024f: Unknown result type (might be due to invalid IL or missing references)
				if (((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsDedicated()) || (Object)(object)__instance == (Object)null)
				{
					return;
				}
				if (!ConfigManager.EffectiveShowHeatLevelInAshlands)
				{
					if ((Object)(object)UIHeatBarArea != (Object)null)
					{
						UIHeatBarArea.SetActive(false);
					}
					return;
				}
				CreateUI(__instance);
				Player localPlayer = Player.m_localPlayer;
				if ((Object)(object)localPlayer == (Object)null || (Object)(object)heatBarFill == (Object)null)
				{
					return;
				}
				float heatLevelFirstDamageThreshold = ((Character)localPlayer).m_heatLevelFirstDamageThreshold;
				if (heatLevelFirstDamageThreshold <= 0f)
				{
					return;
				}
				Traverse val = Traverse.Create((object)localPlayer);
				float value = val.Field("m_lavaHeatLevel").GetValue<float>();
				float value2 = val.Field("m_ashlandsOceanHeatLevel").GetValue<float>();
				float num = ((((Character)localPlayer).InWater() && WorldGenerator.GetAshlandsOceanGradient(((Component)localPlayer).transform.position) >= 0f) ? Mathf.Max(value, value2) : value);
				bool flag = UIController.ShowUI && !IsUIHidden() && !IsLoadScreenActive(__instance);
				if (UIHeatBarArea.activeSelf != flag)
				{
					UIHeatBarArea.SetActive(flag);
				}
				if (flag)
				{
					heatBarFill.fillAmount = Mathf.Clamp01(num / heatLevelFirstDamageThreshold);
					float fillAmount = heatBarFill.fillAmount;
					heatBarText.text = $"{fillAmount * 100f:0}%";
					Color yellow = Color.yellow;
					Color val2 = default(Color);
					((Color)(ref val2))..ctor(1f, 0.549019f, 0f);
					Color red = Color.red;
					Color color = ((fillAmount < 0.5f) ? Color.Lerp(yellow, val2, fillAmount * 2f) : Color.Lerp(val2, red, (fillAmount - 0.5f) * 2f));
					if (fillAmount > 0.8f)
					{
						color.a = 0.6f + 0.4f * Mathf.Sin(Time.time * 4f);
					}
					else
					{
						color.a = 0.8f;
					}
					((Graphic)heatBarFill).color = color;
					bool flag2 = heatBarFill.fillAmount > 0f;
					((Behaviour)heatBarFill).enabled = flag2;
					((Behaviour)heatBarBackground).enabled = flag2;
					((Behaviour)heatBarText).enabled = flag2;
					((Behaviour)heatBarEmojiTMP).enabled = flag2;
					((TMP_Text)heatBarEmojiTMP).text = (flag2 ? "\ud83d\udd25" : "");
				}
			}

			private static bool IsLoadScreenActive(Hud hud)
			{
				return Object.op_Implicit((Object)(object)Hud.instance) && Object.op_Implicit((Object)(object)hud.m_loadingScreen) && ((Component)hud.m_loadingScreen).gameObject.activeSelf;
			}

			private static bool IsUIHidden()
			{
				return Hud.IsUserHidden();
			}
		}

		private static readonly LogManager log = new LogManager("UI Ashlands Heat", LogManager.LogLevel.Warning);

		private static Image heatBarFill;

		private static Image heatBarBackground;

		private static GameObject UIHeatBarArea;

		private static Text heatBarText;

		private static TextMeshProUGUI heatBarEmojiTMP;

		private static void CreateUI(Hud hud)
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: 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_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Expected O, but got Unknown
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: 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_0183: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Expected O, but got Unknown
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_029d: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02db: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)UIHeatBarArea != (Object)null))
			{
				Vector2 sizeDelta = default(Vector2);
				((Vector2)(ref sizeDelta))..ctor(200f, 25f);
				int fontSize = 13;
				int fontSize2 = 10;
				string fontName = "AveriaSansLibre-Bold";
				string fontName2 = "NotoEmoji-Regular SDF";
				UIHeatBarArea = new GameObject("HeatBar");
				UIHeatBarArea.layer = 5;
				UIHeatBarArea.transform.SetParent(hud.m_rootObject.transform.parent, false);
				RectTransform val = UIHeatBarArea.AddComponent<RectTransform>();
				val.anchorMin = new Vector2(0.5f, 0.5f);
				val.anchorMax = new Vector2(0.5f, 0.5f);
				val.pivot = new Vector2(0.5f, 0.5f);
				val.anchoredPosition = new Vector2(0f, 350f);
				val.sizeDelta = sizeDelta;
				UIHeatBarArea.transform.localScale = Vector3.one;
				GameObject val2 = new GameObject("HeatBarBackground");
				val2.transform.SetParent(UIHeatBarArea.transform, false);
				heatBarBackground = val2.AddComponent<Image>();
				RectTransform component = val2.GetComponent<RectTransform>();
				component.anchorMin = Vector2.zero;
				component.anchorMax = Vector2.one;
				component.offsetMin = Vector2.zero;
				component.offsetMax = Vector2.zero;
				((Graphic)heatBarBackground).color = new Color(0f, 0f, 0f, 0.4f);
				((Behaviour)heatBarBackground).enabled = false;
				GameObject val3 = new GameObject("HeatBarFill");
				val3.transform.SetParent(UIHeatBarArea.transform, false);
				heatBarFill = val3.AddComponent<Image>();
				RectTransform component2 = val3.GetComponent<RectTransform>();
				component2.anchorMin = Vector2.zero;
				component2.anchorMax = Vector2.one;
				component2.offsetMin = new Vector2(3f, 3f);
				component2.offsetMax = new Vector2(-3f, -3f);
				Sprite sprite = ((IEnumerable<Sprite>)Resources.FindObjectsOfTypeAll<Sprite>()).FirstOrDefault((Func<Sprite, bool>)((Sprite tempSprite) => ((Object)tempSprite).name == "bar_monster_hp_5"));
				heatBarFill.sprite = sprite;
				heatBarFill.type = (Type)3;
				heatBarFill.fillMethod = (FillMethod)0;
				heatBarFill.fillOrigin = 0;
				heatBarFill.fillAmount = 0f;
				((Behaviour)heatBarFill).enabled = false;
				heatBarText = UIController.CreateTextObject("HeatText", UIHeatBarArea, Color.white, fontName, fontSize, (TextAnchor)4, Vector2.zero, sizeDelta);
				heatBarEmojiTMP = UIController.CreateTMPTextObject("HeatEmojiTMP", UIHeatBarArea, Color.red, fontName2, fontSize2, (TextAlignmentOptions)4100, new Vector2(-2f, 0f), sizeDelta, log);
			}
		}
	}
	internal class UIBoatSpeed : UIController
	{
		[HarmonyPatch(typeof(Ship), "GetSpeed")]
		private static class ShowBoatSpeed_Patch
		{
			private static void Prefix(Ship __instance, ref Rigidbody ___m_body)
			{
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				//IL_005c: Unknown result type (might be due to invalid IL or missing references)
				if ((!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsDedicated()) && ConfigManager.EffectiveShowBoatSpeed)
				{
					if (Object.op_Implicit((Object)(object)__instance) && __instance.HasPlayerOnboard() && (Object)(object)___m_body != (Object)null)
					{
						boatSpeed = Vector3.Dot(___m_body.linearVelocity, ((Component)__instance).transform.forward);
					}
					showBoatSpeedUI = Traverse.Create((object)__instance).Method("HaveControllingPlayer", Array.Empty<object>()).GetValue<bool>();
				}
			}
		}

		[HarmonyPatch(typeof(Hud), "Awake")]
		private static class BoatSpeed_HUDAwakePatch
		{
			private static void Postfix(Hud __instance)
			{
				if ((!((Object)(object)ZNet.instance != (Object)null) || !ZNet.instance.IsDedicated()) && !((Object)(object)__instance == (Object)null) && ConfigManager.EffectiveShowBoatSpeed)
				{
					CreateUI(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(Hud), "Update")]
		private static class BoatSpeed_HUDUpdatePatch
		{
			private static void Postfix(Hud __instance)
			{
				//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
				if (((Object)(object)ZNet.instance != (Object)null && ZNet.instance.IsDedicated()) || (Object)(object)__instance == (Object)null)
				{
					return;
				}
				if (!ConfigManager.EffectiveShowBoatSpeed)
				{
					GameObject uIBoatArea = UIBoatArea;
					if (uIBoatArea != null)
					{
						uIBoatArea.SetActive(false);
					}
					return;
				}
				CreateUI(__instance);
				UpdateBoatSpeedPosition();
				bool flag = showBoatSpeedUI && UIController.ShowUI;
				GameObject uIBoatArea2 = UIBoatArea;
				if (uIBoatArea2 != null)
				{
					uIBoatArea2.SetActive(flag);
				}
				if (flag)
				{
					if ((Object)(object)UIBoatText != (Object)null)
					{
						((Graphic)UIBoatText).color = GetColorFromSpeed(boatSpeed);
						UIBoatText.text = ((boatSpeed > 0f) ? boatSpeed.ToString("0.00") : $"R {Math.Abs(boatSpeed):0.00}");
					}
					if ((Object)(object)UIBoatEmojiTMP != (Object)null)
					{
						((TMP_Text)UIBoatEmojiTMP).text = "⛵";
					}
				}
			}
		}

		private static readonly LogManager log = new LogManager("UI Boat Speed", LogManager.LogLevel.Warning);

		private static float boatSpeed;

		private static bool showBoatSpeedUI;

		internal static GameObject UIBoatArea;

		private static Text UIBoatText;

		private static TextMeshProUGUI UIBoatEmojiTMP;

		private static Color GetColorFromSpeed(float speed)
		{
			//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_0030: 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_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			if (speed < 2.5f)
			{
				return Color.red;
			}
			if (speed < 5f)
			{
				return new Color(1f, 0.549019f, 0f);
			}
			if (speed < 7.5f)
			{
				return Color.yellow;
			}
			return Color.green;
		}

		private static void CreateUI(Hud hud)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: 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)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)UIBoatArea != (Object)null))
			{
				int num = 16;
				string fontName = "AveriaSansLibre-Bold";
				string fontName2 = "NotoEmoji-Regular SDF";
				Vector2 sizeDelta = default(Vector2);
				((Vector2)(ref sizeDelta))..ctor(80f, 30f);
				float num2 = (Game.m_noMap ? (-145f) : (-283f));
				float num3 = -225f;
				UIBoatArea = new GameObject("BoatArea");
				UIBoatArea.layer = 5;
				UIBoatArea.transform.SetParent(hud.m_rootObject.transform);
				RectTransform val = UIBoatArea.AddComponent<RectTransform>();
				val.anchorMin = new Vector2(1f, 1f);
				val.anchorMax = new Vector2(1f, 1f);
				val.anchoredPosition = new Vector2(num2, num3);
				val.sizeDelta = sizeDelta;
				UIBoatArea.transform.localScale = Vector3.one;
				UIBoatText = UIController.CreateTextObject("BoatText", UIBoatArea, Color.white, fontName, num, (TextAnchor)5, new Vector2(-4f, 0f), sizeDelta);
				UIBoatEmojiTMP = UIController.CreateTMPTextObject("BoatEmojiTMP", UIBoatArea, Color.white, fontName2, num + 4, (TextAlignmentOptions)4097, new Vector2(4f, 0f), sizeDelta, log);
			}
		}

		private static void UpdateBoatSpeedPosition()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)UIBoatArea == (Object)null)
			{
				return;
			}
			RectTransform component = UIBoatArea.GetComponent<RectTransform>();
			if (!((Object)(object)component == (Object)null))
			{
				if (ConfigManager.EffectiveStatusEffectsUnderMinimap && !Game.m_noMap)
				{
					component.anchoredPosition = new Vector2(-360f, -25f);
					return;
				}
				float num = (Game.m_noMap ? (-145f) : (-283f));
				component.anchoredPosition = new Vector2(num, -225f);
			}
		}
	}
	internal class UIBossPowerExpiration
	{
		[HarmonyPatch(typeof(StatusEffect), "Stop")]
		private static class StatusEffectStopPatch
		{
			private static void Postfix(StatusEffect __instance)
			{
				if (!ConfigManager.EffectiveShowBossExpirationMessage)
				{
					return;
				}
				Character character = __instance.m_character;
				if (!((Object)(object)character == (Object)null) && character.IsPlayer() && character.IsOwner())
				{
					string name = ((Object)__instance).name;
					if (name.Contains("GP_"))
					{
						string text = Localization.instance.Localize(__instance.m_name);
						log.Info("Forsaken Power expired: " + text);
						character.Message((MessageType)2, text + " Power Expired", 0, (Sprite)null, false);
					}
				}
			}
		}

		private static readonly LogManager log = new LogManager("UI Boss Power Expiration", LogManager.LogLevel.Warning);
	}
	internal class UICharacterStatistics : UIController
	{
		private struct NotableFact
		{
			internal string Title;

			internal string Description;

			internal NotableFact(string title, string description)
			{
				Title = title;
				Description = description;
			}
		}

		[HarmonyPatch(typeof(FejdStartup), "ShowCharacterSelection")]
		private static class FejdStartupShowCharacterSelectionPatch
		{
			private static void Postfix(FejdStartup __instance)
			{
				if (ConfigManager.EffectiveShowCharacterStatistics)
				{
					CreateUI(__instance);
					UpdateStatistics(__instance);
				}
			}
		}

		[HarmonyPatch(typeof(FejdStartup), "UpdateCharacterList")]
		private static class FejdStartupUpdateCharacterListPatch
		{
			private static void Postfix(FejdStartup __instance)
			{
				if (!((Object)(object)UICharacterStatisticsArea == (Object)null))
				{
					if (!ConfigManager.EffectiveShowCharacterStatistics)
					{
						UICharacterStatisticsArea.SetActive(false);
						return;
					}
					UICharacterStatisticsArea.SetActive(true);
					UpdateStatistics(__instance);
				}
			}
		}

		private static readonly LogManager log = new LogManager("UI Character Statistics", LogManager.LogLevel.Warning);

		private static readonly FieldInfo profilesField = AccessTools.Field(typeof(FejdStartup), "m_profiles");

		private static readonly FieldInfo profileIndexField = AccessTools.Field(typeof(FejdStartup), "m_profileIndex");

		private static readonly FieldInfo characterSelectScreenField = AccessTools.Field(typeof(FejdStartup), "m_characterSelectScreen");

		private static readonly FieldInfo playerInstanceField = AccessTools.Field(typeof(FejdStartup), "m_playerInstance");

		private static readonly MethodInfo getSkillMethod = AccessTools.Method(typeof(Skills), "GetSkill", new Type[1] { typeof(SkillType) }, (Type[])null);

		private static GameObject UICharacterStatisticsArea;

		private static Text statisticsValues;

		private static Text playtimeText;

		private static Text notableFactTitle;

		private static Text notableFactDescription;

		private static int lastFactProfileIndex = -1;

		private static NotableFact currentNotableFact;

		private static void CreateUI(FejdStartup startup)
		{
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Expected O, but got Unknown
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: 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_0160: 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_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_0211: Unknown result type (might be due to invalid IL or missing references)
			//IL_0255: Unknown result type (might be due to invalid IL or missing references)
			//IL_026c: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0307: Unknown result type (might be due to invalid IL or missing references)
			//IL_031e: Unknown result type (might be due to invalid IL or missing references)
			//IL_032d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			//IL_036c: Unknown result type (might be due to invalid IL or missing references)
			//IL_037b: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)UICharacterStatisticsArea != (Object)null))
			{
				GameObject characterSelectScreen = GetCharacterSelectScreen(startup);
				if ((Object)(object)characterSelectScreen == (Object)null)
				{
					log.Warn("Could not find the character selection screen.");
					return;
				}
				UICharacterStatisticsArea = new GameObject("CharacterStatisticsArea");
				UICharacterStatisticsArea.layer = 5;
				UICharacterStatisticsArea.transform.SetParent(characterSelectScreen.transform, false);
				RectTransform val = UICharacterStatisticsArea.AddComponent<RectTransform>();
				val.anchorMin = new Vector2(1f, 0.5f);
				val.anchorMax = new Vector2(1f, 0.5f);
				val.pivot = new Vector2(1f, 0.5f);
				val.anchoredPosition = new Vector2(-60f, 10f);
				val.sizeDelta = new Vector2(390f, 650f);
				((Transform)val).localScale = Vector3.one;
				Image val2 = UICharacterStatisticsArea.AddComponent<Image>();
				((Graphic)val2).color = new Color(0f, 0f, 0f, 0.45f);
				CreateFrame(UICharacterStatisticsArea);
				UIController.CreateTextObject("CharacterStatisticsTitle", UICharacterStatisticsArea, new Color(1f, 0.65f, 0.15f), "AveriaSansLibre-Bold", 20, (TextAnchor)4, new Vector2(0f, 290f), new Vector2(370f, 30f)).text = "CHARACTER STATISTICS";
				playtimeText = UIController.CreateTextObject("CharacterStatisticsPlaytime", UICharacterStatisticsArea, new Color(0.9f, 0.9f, 0.85f), "AveriaSansLibre-Bold", 14, (TextAnchor)4, new Vector2(0f, 263f), new Vector2(370f, 25f));
				Text val3 = UIController.CreateTextObject("CharacterStatisticsLabels", UICharacterStatisticsArea, new Color(0.9f, 0.9f, 0.85f), "AveriaSansLibre-Bold", 15, (TextAnchor)0, new Vector2(-57f, 12f), new Vector2(250f, 460f));
				val3.supportRichText = true;
				val3.lineSpacing = 1.05f;
				val3.text = "<color=#FFA626>COMBAT & SURVIVAL</color>\nFoes Dispatched\nBosses Demoted\nValhalla Rejections\nLongest Survival\nArrows Liberated\nWalks of Shame\n\n<color=#FFA626>CRAFT & HOMESTEAD</color>\nItems Crafted\nItems Upgraded\nPieces Built\nRocks and Ores Brutally Smashed\nTrees Brutally Murdered\nCreatures Tamed\nFish Acquired Legally\nTime at Home\n\n<color=#FFA626>TRAVEL & EXPLORATION</color>\nDistance Traveled\nDistance Sailed\nPortals Used\nJumps";
				statisticsValues = UIController.CreateTextObject("CharacterStatisticsValues", UICharacterStatisticsArea, new Color(1f, 0.75f, 0.28f), "AveriaSansLibre-Bold", 15, (TextAnchor)2, new Vector2(125f, 12f), new Vector2(100f, 460f));
				statisticsValues.lineSpacing = 1.05f;
				UIController.CreateTextObject("CharacterStatisticsNotableFactHeading", UICharacterStatisticsArea, new Color(1f, 0.65f, 0.15f), "AveriaSansLibre-Bold", 15, (TextAnchor)4, new Vector2(0f, -230f), new Vector2(370f, 25f)).text = "NOTABLE RANDOM FACT";
				notableFactTitle = UIController.CreateTextObject("CharacterStatisticsNotableFactTitle", UICharacterStatisticsArea, new Color(1f, 0.75f, 0.28f), "AveriaSansLibre-Bold", 16, (TextAnchor)4, new Vector2(0f, -262f), new Vector2(370f, 25f));
				notableFactDescription = UIController.CreateTextObject("CharacterStatisticsNotableFactDescription", UICharacterStatisticsArea, new Color(0.9f, 0.9f, 0.85f), "AveriaSansLibre-Bold", 13, (TextAnchor)4, new Vector2(0f, -292f), new Vector2(350f, 40f));
			}
		}

		private static void CreateFrame(GameObject parent)
		{
			//IL_0028: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			Color color = default(Color);
			((Color)(ref color))..ctor(0.72f, 0.4f, 0.1f, 0.85f);
			float num = 2f;
			CreateFrameEdge("FrameTop", parent, color, new Vector2(0f, 324f), new Vector2(390f, num));
			CreateFrameEdge("FrameBottom", parent, color, new Vector2(0f, -324f), new Vector2(390f, num));
			CreateFrameEdge("FrameLeft", parent, color, new Vector2(-194f, 0f), new Vector2(num, 650f));
			CreateFrameEdge("FrameRight", parent, color, new Vector2(194f, 0f), new Vector2(num, 650f));
		}

		private static void CreateFrameEdge(string name, GameObject parent, Color color, Vector2 position, Vector2 size)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_002b: 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_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.layer = 5;
			val.transform.SetParent(parent.transform, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchoredPosition = position;
			val2.sizeDelta = size;
			((Transform)val2).localScale = Vector3.one;
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = color;
			((Graphic)val3).raycastTarget = false;
		}

		private static void UpdateStatistics(FejdStartup startup)
		{
			if (!((Object)(object)statisticsValues == (Object)null))
			{
				PlayerProfile selectedProfile = GetSelectedProfile(startup);
				if (selectedProfile == null)
				{
					UICharacterStatisticsArea.SetActive(false);
					return;
				}
				UICharacterStatisticsArea.SetActive(true);
				int num = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)6));
				int num2 = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)85));
				int num3 = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)0));
				int num4 = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)129));
				int num5 = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)51));
				int num6 = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)52));
				int num7 = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)13));
				int num8 = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)14));
				int num9 = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)2));
				int num10 = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)38));
				int num11 = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)28));
				int num12 = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)48));
				int num13 = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)160));
				float stat = GetStat(selectedProfile, (PlayerStatType)21);
				float num14 = GetStat(selectedProfile, (PlayerStatType)16) / 1000f;
				float num15 = GetStat(selectedProfile, (PlayerStatType)19) / 1000f;
				int num16 = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)15));
				int num17 = Mathf.RoundToInt(GetStat(selectedProfile, (PlayerStatType)3));
				playtimeText.text = "Playtime: " + FormatPlaytime(selectedProfile);
				statisticsValues.text = "\n" + $"{num:N0}\n" + $"{num2:N0}\n" + $"{num3:N0}\n" + $"{num4:N0} days\n" + $"{num5:N0}\n" + $"{num6:N0}\n\n" + "\n" + $"{num7:N0}\n" + $"{num8:N0}\n" + $"{num9:N0}\n" + $"{num10:N0}\n" + $"{num11:N0}\n" + $"{num12:N0}\n" + $"{num13:N0}\n" + FormatTime(stat) + "\n\n\n" + $"{num14:N1} km\n" + $"{num15:N1} km\n" + $"{num16:N0}\n" + $"{num17:N0}";
				UpdateNotableFact(startup, selectedProfile);
			}
		}

		private static GameObject GetCharacterSelectScreen(FejdStartup startup)
		{
			if (characterSelectScreenField == null)
			{
				log.Warn("Could not find m_characterSelectScreen in FejdStartup.");
				return null;
			}
			object value = characterSelectScreenField.GetValue(startup);
			GameObject val = (GameObject)((value is GameObject) ? value : null);
			if (val != null)
			{
				return val;
			}
			Component val2 = (Component)((value is Component) ? value : null);
			if (val2 != null)
			{
				return val2.gameObject;
			}
			log.Warn("m_characterSelectScreen was not a GameObject or Component.");
			return null;
		}

		private static PlayerProfile GetSelectedProfile(FejdStartup startup)
		{
			if (profilesField == null || profileIndexField == null)
			{
				log.Warn("Could not find character profile fields in FejdStartup.");
				return null;
			}
			if (!(profilesField.GetValue(startup) is List<PlayerProfile> { Count: not 0 } list))
			{
				return null;
			}
			int num = (int)profileIndexField.GetValue(startup);
			if (num < 0 || num >= list.Count)
			{
				return null;
			}
			return list[num];
		}

		private static float GetStat(PlayerProfile profile, PlayerStatType statType)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			if (profile.m_playerStats == null || profile.m_playerStats.Length == 0)
			{
				return 0f;
			}
			if (profile.m_playerStats[0] == null || profile.m_playerStats[0].m_stats == null)
			{
				return 0f;
			}
			float value;
			return profile.m_playerStats[0].m_stats.TryGetValue(statType, out value) ? value : 0f;
		}

		private static string FormatPlaytime(PlayerProfile profile)
		{
			float totalSeconds = GetStat(profile, (PlayerStatType)21) + GetStat(profile, (PlayerStatType)22);
			return FormatTime(totalSeconds);
		}

		private static string FormatTime(float totalSeconds)
		{
			int num = Mathf.FloorToInt(totalSeconds / 60f);
			int num2 = num / 60;
			int num3 = num % 60;
			return $"{num2:N0}h {num3:00}m";
		}

		private static void UpdateNotableFact(FejdStartup startup, PlayerProfile profile)
		{
			int num = (int)profileIndexField.GetValue(startup);
			if (num != lastFactProfileIndex)
			{
				lastFactProfileIndex = num;
				currentNotableFact = GetRandomNotableFact(startup, profile);
			}
			notableFactTitle.text = currentNotableFact.Title;
			notableFactDescription.text = currentNotableFact.Description;
		}

		private static NotableFact GetRandomNotableFact(FejdStartup startup, PlayerProfile profile)
		{
			List<NotableFact> list = new List<NotableFact>();
			AddDeathFact(list, profile, (PlayerStatType)68, 1, "The Forest Remembers", "Killed by a falling tree");
			AddDeathFact(list, profile, (PlayerStatType)65, 1, "Curiosity Won", "Claimed by the edge of the world");
			AddDeathFact(list, profile, (PlayerStatType)67, 1, "Occupational Hazard", "Killed by a cart");
			AddDeathFact(list, profile, (PlayerStatType)105, 1, "Flight Test Failed", "Killed by a catapult");
			AddDeathFact(list, profile, (PlayerStatType)203, 1, "Workplace Safety Violation", "Killed by a drawbridge");
			AddDeathFact(list, profile, (PlayerStatType)108, 1, "Disposal Error", "Killed by the obliterator");
			AddDeathFact(list, profile, (PlayerStatType)71, 1, "Security System Working as Intended", "Killed by a turret");
			AddDeathFact(list, profile, (PlayerStatType)72, 1, "Captain Went Down With the Ship", "Killed by a boat");
			AddDeathFact(list, profile, (PlayerStatType)204, 1, "The Floor Was Lava", "Killed by Ashlands lava");
			AddDeathFact(list, profile, (PlayerStatType)107, 1, "Hostile Waters", "Killed by the Ashlands ocean");
			AddDeathFact(list, profile, (PlayerStatType)58, 3, "Natural Enemy: Gravity", "Died from falling");
			AddDeathFact(list, profile, (PlayerStatType)59, 2, "Swimming Lessons Recommended", "Drowned");
			AddDeathFact(list, profile, (PlayerStatType)63, 2, "Ventilation Required", "Died from smoke inhalation");
			AddDeathFact(list, profile, (PlayerStatType)69, 2, "Own Worst Enemy", "Died by your own hand");
			AddDeathFact(list, profile, (PlayerStatType)60, 3, "Fire Safety Optional", "Burned to death");
			AddDeathFact(list, profile, (PlayerStatType)61, 3, "Should Have Packed a Cloak", "Frozen to death");
			AddDeathFact(list, profile, (PlayerStatType)62, 3, "Poison Control", "Died from poison");
			int num = Mathf.RoundToInt(GetStat(profile, (PlayerStatType)86));
			if (num >= 5)
			{
				list.Add(new NotableFact("The Finishing Touch", $"Dealt the final blow to {num:N0} bosses."));
			}
			int num2 = Mathf.RoundToInt(GetStat(profile, (PlayerStatType)159));
			if (num2 >= 10)
			{
				list.Add(new NotableFact("The Ones That Got Away", $"Lost {num2:N0} hooked fish."));
			}
			int num3 = Mathf.RoundToInt(GetStat(profile, (PlayerStatType)45));
			if (num3 >= 5)
			{
				list.Add(new NotableFact("Odin's HR Has Been Notified", string.Format("Hit a raven {0:N0} {1}.", num3, Pluralize(num3, "time", "times"))));
			}
			int num4 = Mathf.RoundToInt(GetStat(profile, (PlayerStatType)50));
			if (num4 >= 250)
			{
				list.Add(new NotableFact("Necromancy Is a Hobby", $"Summoned {num4:N0} skeletons."));
			}
			int num5 = Mathf.RoundToInt(GetStat(profile, (PlayerStatType)53));
			if (num5 >= 5)
			{
				list.Add(new NotableFact("Retrieval Specialist", $"Recovered {num5:N0} other players' tombstones."));
			}
			int num6 = Mathf.RoundToInt(GetStat(profile, (PlayerStatType)74));
			int num7 = Mathf.RoundToInt(GetStat(profile, (PlayerStatType)75));
			int num8 = num6 - num7;
			if (num6 > 0 && num8 >= 100 && (float)num8 >= (float)num6 * 0.1f)
			{
				list.Add(new NotableFact("Born in a Barn", $"Opened {num8:N0} more doors than you closed."));
			}
			int num9 = Mathf.RoundToInt(GetStat(profile, (PlayerStatType)136));
			if (num9 >= 5)
			{
				list.Add(new NotableFact("Thar She Blows", string.Format("Sank {0:N0} {1}.", num9, Pluralize(num9, "leviathan", "leviathans"))));
			}
			int num10 = Mathf.RoundToInt(GetStat(profile, (PlayerStatType)133)) + Mathf.RoundToInt(GetStat(profile, (PlayerStatType)135));
			if (num10 >= 10)
			{
				list.Add(new NotableFact("Treasure Hunter", $"Discovered {num10:N0} hidden treasures."));
			}
			float num11 = GetStat(profile, (PlayerStatType)150) / 1000f;
			if (num11 >= 100f)
			{
				list.Add(new NotableFact("Captain", $"Sailed {num11:N1} km at the helm."));
			}
			int num12 = Mathf.RoundToInt(GetStat(profile, (PlayerStatType)168));
			int num13 = Mathf.RoundToInt(GetStat(profile, (PlayerStatType)170));
			if (num12 >= 100 && (float)num13 >= (float)num12 * 0.5f)
			{
				list.Add(new NotableFact("Measure Twice, Build Once?", $"Removed {num13:N0} pieces after building {num12:N0}."));
			}
			Skills selectedCharacterSkills = GetSelectedCharacterSkills(startup);
			if ((Object)(object)selectedCharacterSkills != (Object)null)
			{
				if (AreAllVanillaSkillsMaxed(selectedCharacterSkills))
				{
					list.Add(new NotableFact("Master of Everything", "Reached level 100 in every skill."));
				}
				else
				{
					AddSkillFact(list, selectedCharacterSkills, (SkillType)100, "Mountain Goat", "Jump");
					AddSkillFact(list, selectedCharacterSkills, (SkillType)103, "Still Faster Than a Boat", "Swim");
					AddSkillFact(list, selectedCharacterSkills, (SkillType)101, "You Were Never Here", "Sneak");
					AddSkillFact(list, selectedCharacterSkills, (SkillType)13, "The Forest Definitely Remembers", "Wood Cutting");
					AddSkillFact(list, selectedCharacterSkills, (SkillType)12, "Professional Rock Argument", "Pickaxes");
					AddSkillFact(list, selectedCharacterSkills, (SkillType)6, "Not Today", "Blocking");
					AddSkillFact(list, selectedCharacterSkills, (SkillType)102, "Cardio Is a Lifestyle", "Run");
					AddSkillFact(list, selectedCharacterSkills, (SkillType)104, "Fish Fear Me", "Fishing");
					AddSkillFact(list, selectedCharacterSkills, (SkillType)110, "Born in the Saddle", "Ride");
					AddSkillFact(list, selectedCharacterSkills, (SkillType)106, "Outstanding in the Field", "Farming");
					AddSkillFact(list, selectedCharacterSkills, (SkillType)105, "Yes, Chef", "Cooking");
				}
			}
			if (list.Count == 0)
			{
				return new NotableFact("The Saga Has Just Begun", "No particularly notable exploits yet.");
			}
			return list[Random.Range(0, list.Count)];
		}

		private static void AddDeathFact(List<NotableFact> facts, PlayerProfile profile, PlayerStatType statType, int threshold, string title, string description)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.RoundToInt(GetStat(profile, statType));
			if (num >= threshold)
			{
				facts.Add(new NotableFact(title, string.Format("{0} {1:N0} {2}.", description, num, Pluralize(num, "time", "times"))));
			}
		}

		private static string Pluralize(int count, string singular, string plural)
		{
			return (count == 1) ? singular : plural;
		}

		private static Skills GetSelectedCharacterSkills(FejdStartup startup)
		{
			if (playerInstanceField == null)
			{
				log.Warn("Could not find m_playerInstance in FejdStartup.");
				return null;
			}
			object value = playerInstanceField.GetValue(startup);
			Player val = null;
			Player val2 = (Player)((value is Player) ? value : null);
			if (val2 != null)
			{
				val = val2;
			}
			else
			{
				GameObject val3 = (GameObject)((value is GameObject) ? value : null);
				if (val3 != null)
				{
					val = val3.GetComponent<Player>();
				}
				else
				{
					Component val4 = (Component)((value is Component) ? value : null);
					if (val4 != null)
					{
						val = val4.GetComponent<Player>();
					}
				}
			}
			return (val != null) ? ((Character)val).GetSkills() : null;
		}

		private static void AddSkillFact(List<NotableFact> facts, Skills skills, SkillType skillType, string title, string skillName)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			Skill skill = GetSkill(skills, skillType);
			if (skill != null && !(skill.m_level < 100f))
			{
				facts.Add(new NotableFact(title, "Reached level 100 in " + skillName + "."));
			}
		}

		private static Skill GetSkill(Skills skills, SkillType skillType)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (getSkillMethod == null)
			{
				log.Warn("Could not find Skills.GetSkill.");
				return null;
			}
			object? obj = getSkillMethod.Invoke(skills, new object[1] { skillType });
			return (Skill)((obj is Skill) ? obj : null);
		}

		private static bool AreAllVanillaSkillsMaxed(Skills skills)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Invalid comparison between Unknown and I4
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			if (skills.m_skills == null || skills.m_skills.Count == 0)
			{
				return false;
			}
			bool result = false;
			foreach (SkillDef skill2 in skills.m_skills)
			{
				if (skill2 != null && (int)skill2.m_skill != 0 && Enum.IsDefined(typeof(SkillType), skill2.m_skill))
				{
					result = true;
					Skill skill = GetSkill(skills, skill2.m_skill);
					if (skill == null || skill.m_level < 100f)
					{
						return false;
					}
				}
			}
			return result;
		}
	}
	internal class UIContainerContents : UIController
	{
		private class ContainerItemEntry
		{
			internal ItemData Item;

			internal string LocalizedName;

			internal int Count;

			internal ContainerItemEntry(ItemData item, string localizedName)
			{
				Item = item;
				LocalizedName = localizedName;
				Count = 0;
			}
		}

		[HarmonyPatch(typeof(Hud), "UpdateCrosshair")]
		private static class HudUpdateCrosshairPatch
		{
			private static void Prefix()
			{
				HideIcons();
			}
		}

		private static readonly LogManager log = new LogManager("UI Container Contents", LogManager.LogLevel.Warning);

		private static GameObject containerContentsArea;

		private static readonly List<Image> itemIcons = new List<Image>();

		private static readonly List<Text> itemCounts = new List<Text>();

		private static Text othersText;

		private const int MaxDisplayedItems = 10;

		private const float IconSize = 32f;

		private const float IconSpacing = 3f;

		private const int CountFontSize = 12;

		private const int OthersFontSize = 11;

		private const int HorizontalColumns = 5;

		private const int VerticalRows = 5;

		private const float GridLeftOffset = -1f;

		private const float GridTopOffset = 20f;

		private const float OthersGap = 7f;

		private static List<ContainerItemEntry> GetContainerItems(Inventory inventory)
		{
			List<ContainerItemEntry> list = new List<ContainerItemEntry>();
			Dictionary<string, ContainerItemEntry> dictionary = new Dictionary<string, ContainerItemEntry>();
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem?.m_shared != null)
				{
					string name = allItem.m_shared.m_name;
					if (!dictionary.TryGetValue(name, out var value))
					{
						string localizedName = Localization.instance.Localize(allItem.m_shared.m_name);
						value = new ContainerItemEntry(allItem, localizedName);
						dictionary.Add(name, value);
						list.Add(value);
					}
					value.Count += allItem.m_stack;
				}
			}
			return list;
		}

		internal static string GetContainerInventoryList(Container container, Inventory inventory)
		{
			//IL_015f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0173: Unknown result type (might be due to invalid IL or missing references)
			//IL_01dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			ConfigManager.ContainerContentsMode effectiveContainerContentsChoice = ConfigManager.EffectiveContainerContentsChoice;
			if (effectiveContainerContentsChoice == ConfigManager.ContainerContentsMode.Off)
			{
				return "";
			}
			if (CompatibilityManager.TweaksIsContainerSealed(container))
			{
				return "This chest is sealed.";
			}
			List<ContainerItemEntry> containerItems = GetContainerItems(inventory);
			if (containerItems.Count == 0)
			{
				return "";
			}
			if (effectiveContainerContentsChoice == ConfigManager.ContainerContentsMode.IconsHorizontal || effectiveContainerContentsChoice == ConfigManager.ContainerContentsMode.IconsVertical)
			{
				ShowIcons(containerItems, effectiveContainerContentsChoice);
				return "";
			}
			if (effectiveContainerContentsChoice != ConfigManager.ContainerContentsMode.Text)
			{
				return "";
			}
			StringBuilder stringBuilder = new StringBuilder();
			int num = 0;
			int count = containerItems.Count;
			int num2 = 2;
			for (int i = 0; i < Mathf.Min(containerItems.Count, 10); i++)
			{
				num2 = Mathf.Max(num2, containerItems[i].Count.ToString().Length);
			}
			if (count > 10)
			{
				num2 = Mathf.Max(num2, $"+{count - 10}".Length);
			}
			int num3 = 25 + Mathf.Max(0, num2 - 2) * 10;
			foreach (ContainerItemEntry item in containerItems)
			{
				if (num >= 10)
				{
					break;
				}
				string arg = UIDetailedHovers.PaintTextIfEnabled(item.Count.ToString(), Color.yellow);
				string arg2 = UIDetailedHovers.PaintTextIfEnabled(item.LocalizedName, Color.gray);
				stringBuilder.AppendLine($"{arg}<pos={num3}>{arg2}");
				num++;
			}
			if (count > 10)
			{
				string arg3 = UIDetailedHovers.PaintTextIfEnabled($"+{count - 10}", Color.yellow);
				string arg4 = UIDetailedHovers.PaintTextIfEnabled("Others", Color.gray);
				stringBuilder.AppendLine($"{arg3}<pos={num3}>{arg4}");
			}
			return stringBuilder.ToString().TrimEnd(Array.Empty<char>());
		}

		private static void ShowIcons(List<ContainerItemEntry> items, ConfigManager.ContainerContentsMode mode)
		{
			if ((Object)(object)Hud.instance == (Object)null || (Object)(object)Hud.instance.m_hoverName == (Object)null)
			{
				return;
			}
			EnsureIconUI();
			if ((Object)(object)containerContentsArea == (Object)null)
			{
				return;
			}
			ConfigureIconLayout(mode);
			containerContentsArea.SetActive(true);
			int num = Mathf.Min(items.Count, 10);
			PositionIcons(num, mode);
			for (int i = 0; i < 10; i++)
			{
				if (i < num)
				{
					UpdateItemIcon(items[i], i);
					((Component)itemIcons[i]).gameObject.SetActive(true);
				}
				else
				{
					((Component)itemIcons[i]).gameObject.SetActive(false);
				}
			}
			int num2 = items.Count - 10;
			if (num2 > 0)
			{
				othersText.text = $"+{num2} Others";
				((Component)othersText).gameObject.SetActive(true);
			}
			else
			{
				((Component)othersText).gameObject.SetActive(false);
			}
		}

		private static void EnsureIconUI()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)containerContentsArea != (Object)null) && !((Object)(object)Hud.instance == (Object)null) && !((Object)(object)Hud.instance.m_hoverName == (Object)null))
			{
				containerContentsArea = new GameObject("ContainerContentsArea");
				containerContentsArea.layer = 5;
				containerContentsArea.transform.SetParent(((TMP_Text)Hud.instance.m_hoverName).transform, false);
				RectTransform val = containerContentsArea.AddComponent<RectTransform>();
				val.anchorMin = new Vector2(0.5f, 0.5f);
				val.anchorMax = new Vector2(0.5f, 0.5f);
				val.pivot = new Vector2(0.5f, 1f);
				val.anchoredPosition = Vector2.zero;
				val.sizeDelta = Vector2.zero;
				itemIcons.Clear();
				itemCounts.Clear();
				for (int i = 0; i < 10; i++)
				{
					CreateIconSlot(i);
				}
				othersText = UIController.CreateTextObject("ContainerContentsOthers", containerContentsArea, Color.white, "AveriaSansLibre-Bold", 11, (TextAnchor)3, Vector2.zero, new Vector2(220f, 25f));
				((Graphic)othersText).raycastTarget = false;
				RectTransform component = ((Component)othersText).GetComponent<RectTransform>();
				component.anchorMin = new Vector2(0.5f, 1f);
				component.anchorMax = new Vector2(0.5f, 1f);
				component.pivot = new Vector2(0f, 1f);
				((Component)othersText).gameObject.SetActive(false);
			}
		}

		private static void CreateIconSlot(int index)
		{
			//IL_0016: 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_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			Image val = UIController.CreateUIImageObject($"ContainerItemIcon_{index}", containerContentsArea, Vector2.zero, new Vector2(32f, 32f));
			RectTransform component = ((Component)val).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0.5f, 1f);
			component.anchorMax = new Vector2(0.5f, 1f);
			component.pivot = new Vector2(0.5f, 1f);
			val.preserveAspect = true;
			((Graphic)val).raycastTarget = false;
			Text val2 = UIController.CreateTextObject($"ContainerItemCount_{index}", ((Component)val).gameObject, Color.white, "AveriaSansLibre-Bold", 12, (TextAnchor)8, Vector2.zero, new Vector2(32f, 32f));
			RectTransform component2 = ((Component)val2).GetComponent<RectTransform>();
			component2.anchorMin = Vector2.zero;
			component2.anchorMax = Vector2.one;
			component2.offsetMin = Vector2.zero;
			component2.offsetMax = Vector2.zero;
			((Graphic)val2).raycastTarget = false;
			itemIcons.Add(val);
			itemCounts.Add(val2);
			((Component)val).gameObject.SetActive(false);
		}

		private static void ConfigureIconLayout(ConfigManager.ContainerContentsMode mode)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			bool flag = mode == ConfigManager.ContainerContentsMode.IconsVertical;
			int num = (flag ? 2 : 5);
			int num2 = (flag ? 5 : 2);
			float num3 = (float)num * 32f + (float)(num - 1) * 3f;
			float num4 = (float)num2 * 32f + (float)(num2 - 1) * 3f;
			RectTransform component = containerContentsArea.GetComponent<RectTransform>();
			RectTransform component2 = ((Component)Hud.instance.m_hoverName).GetComponent<RectTransform>();
			float num5;
			if (!((Object)(object)component2 != (Object)null))
			{
				num5 = 350f;
			}
			else
			{
				Rect rect = component2.rect;
				num5 = ((Rect)(ref rect)).width;
			}
			float num6 = num5;
			float num7 = (0f - num6) / 2f + num3 / 2f + -1f;
			component.anchoredPosition = new Vector2(num7, 20f);
			component.sizeDelta = new Vector2(num3, num4);
			for (int i = 0; i < itemIcons.Count; i++)
			{
				((Graphic)itemIcons[i]).rectTransform.sizeDelta = new Vector2(32f, 32f);
				itemCounts[i].fontSize = 12;
			}
			othersText.fontSize = 11;
			RectTransform component3 = ((Component)othersText).GetComponent<RectTransform>();
			component3.anchoredPosition = new Vector2((0f - num3) / 2f, 0f - (num4 + 7f));
		}

		private static void PositionIcons(int shown, ConfigManager.ContainerContentsMode mode)
		{
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			bool flag = mode == ConfigManager.ContainerContentsMode.IconsVertical;
			int num = (flag ? 2 : 5);
			float num2 = (float)num * 32f + (float)(num - 1) * 3f;
			for (int i = 0; i < shown; i++)
			{
				int num3;
				int num4;
				if (flag)
				{
					num3 = i % 5;
					num4 = i / 5;
				}
				else
				{
					num3 = i / 5;
					num4 = i % 5;
				}
				float num5 = (0f - num2) / 2f + 16f + (float)num4 * 35f;
				float num6 = (float)(-num3) * 35f;
				((Graphic)itemIcons[i]).rectTransform.anchoredPosition = new Vector2(num5, num6);
			}
		}

		private static void UpdateItemIcon(ContainerItemEntry entry, int index)
		{
			Sprite icon = entry.Item.GetIcon();
			if ((Object)(object)icon == (Object)null)
			{
				log.Warn("No icon found for container item '" + entry.LocalizedName + "'.");
				itemIcons[index].sprite = null;
				itemCounts[index].text = "";
			}
			else
			{
				itemIcons[index].sprite = icon;
				itemCounts[index].text = ((entry.Count > 1) ? entry.Count.ToString() : "");
			}
		}

		private static void HideIcons()
		{
			if (!((Object)(object)containerContentsArea == (Object)null))
			{
				containerContentsArea.SetActive(false);
			}
		}
	}
	internal class UIController
	{
		[HarmonyPatch(typeof(Hud), "Awake")]
		private static class HudAwakePatch
		{
			private static void Prefix()
			{
				TMP_FontAsset val = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset font) => ((Object)font).name == "NotoEmoji-Regular SDF"));
				if ((Object)(object)val != (Object)null)
				{
					TMP_Settings.defaultFontAsset = val;
					log.Info("Set default TMP font asset to NotoEmoji-Regular SDF.");
				}
				else
				{
					log.Warn("NotoEmoji font not found.");
				}
			}
		}

		private static readonly LogManager log = new LogManager("UI Controller", LogManager.LogLevel.Warning);

		internal static bool ShowUI = true;

		internal static bool ShowPlayerList = true;

		public static void UpdateUIDisplay()
		{
			if (Input.GetKeyDown((KeyCode)277))
			{
				ShowUI = !ShowUI;
			}
			if (Input.GetKeyDown((KeyCode)278))
			{
				ShowPlayerList = !ShowPlayerList;
			}
		}

		internal static Text CreateTextObject(string name, GameObject parent, Color textColor, string fontName, int fontSize, TextAnchor alignment, Vector2 position, Vector2 sizeDelta)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.layer = 5;
			val.transform.SetParent(parent.transform, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchoredPosition = position;
			val2.sizeDelta = sizeDelta;
			((Transform)val2).localScale = Vector3.one;
			Text val3 = val.AddComponent<Text>();
			((Graphic)val3).color = textColor;
			val3.font = ((IEnumerable<Font>)Resources.FindObjectsOfTypeAll<Font>()).FirstOrDefault((Func<Font, bool>)((Font font) => ((Object)font).name == fontName));
			val3.fontSize = fontSize;
			val3.alignment = alignment;
			Outline val4 = val.AddComponent<Outline>();
			((Shadow)val4).effectColor = Color.black;
			((Shadow)val4).effectDistance = new Vector2(1f, -1f);
			((Shadow)val4).useGraphicAlpha = true;
			((MonoBehaviour)val4).useGUILayout = true;
			return val3;
		}

		internal static TextMeshProUGUI CreateTMPTextObject(string name, GameObject parent, Color textColor, string fontName, int fontSize, TextAlignmentOptions alignment, Vector2 position, Vector2 sizeDelta, LogManager specificLog)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.layer = 5;
			val.transform.SetParent(parent.transform, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchoredPosition = position;
			val2.sizeDelta = sizeDelta;
			((Transform)val2).localScale = Vector3.one;
			TextMeshProUGUI val3 = val.AddComponent<TextMeshProUGUI>();
			((Graphic)val3).color = textColor;
			((TMP_Text)val3).font = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset font) => ((Object)font).name == fontName));
			((TMP_Text)val3).fontSize = fontSize;
			((TMP_Text)val3).alignment = alignment;
			((TMP_Text)val3).text = "";
			if ((Object)(object)((TMP_Text)val3).font != (Object)null)
			{
				((TMP_Text)val3).fontMaterial = (Material)((!((Object)(object)((TMP_Text)val3).fontMaterial != (Object)null)) ? ((object)((TMP_Asset)((TMP_Text)val3).font).material) : ((object)new Material(((TMP_Text)val3).fontMaterial)));
				if (((TMP_Text)val3).fontMaterial.HasProperty(ShaderUtilities.ID_OutlineWidth) && ((TMP_Text)val3).fontMaterial.HasProperty(ShaderUtilities.ID_OutlineColor))
				{
					((TMP_Text)val3).fontMaterial.SetFloat(ShaderUtilities.ID_OutlineWidth, 0.125f);
					((TMP_Text)val3).fontMaterial.SetColor(ShaderUtilities.ID_OutlineColor, Color.black);
				}
				((TMP_Text)val3).havePropertiesChanged = true;
				((Graphic)val3).SetAllDirty();
				((TMP_Text)val3).ForceMeshUpdate(false, false);
			}
			else
			{
				specificLog.Warn("Font material for '" + fontName + "' is null or font is missing. Skipping outline setup.");
			}
			return val3;
		}

		internal static Image CreateUIImageObject(string name, GameObject parent, Vector2 position, Vector2 sizeDelta)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_002b: 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_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.layer = 5;
			val.transform.SetParent(parent.transform, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchoredPosition = position;
			val2.sizeDelta = sizeDelta;
			((Transform)val2).localScale = Vector3.one;
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = Color.white;
			return val3;
		}

		private static GameObject CreateSideCapsBorder(string objectName, GameObject parent, string spriteName, Color color, Vector2 capSize, LogManager specificLog)
		{
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Expected O, but got Unknown
			//IL_0075: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			Sprite val = IconManager.LoadHudIcon(spriteName);
			float horizontalInset = 3f;
			if ((Object)(object)val == (Object)null)
			{
				specificLog.Warn("Could not load HUD border cap '" + spriteName + "'.");
				return null;
			}
			GameObject val2 = new GameObject(objectName);
			val2.layer = 5;
			val2.transform.SetParent(parent.transform, false);
			val2.transform.SetSiblingIndex(1);
			RectTransform val3 = val2.AddComponent<RectTransform>();
			val3.anchorMin = Vector2.zero;
			val3.anchorMax = Vector2.one;
			val3.offsetMin = Vector2.zero;
			val3.offsetMax = Vector2.zero;
			((Transform)val3).localScale = Vector3.one;
			LayoutElement val4 = val2.AddComponent<LayoutElement>();
			val4.ignoreLayout = true;
			CreateSideCap("Left", val2, val, color, capSize, mirror: false, horizontalInset);
			CreateSideCap("Right", val2, val, color, capSize, mirror: true, horizontalInset);
			return val2;
		}

		private static void CreateSideCap(string objectName, GameObject parent, Sprite sprite, Color color, Vector2 capSize, bool mirror, float horizontalInset)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: 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_0052: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0129: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(objectName);
			val.layer = 5;
			val.transform.SetParent(parent.transform, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			if (mirror)
			{
				val2.anchorMin = new Vector2(1f, 0.5f);
				val2.anchorMax = new Vector2(1f, 0.5f);
				val2.pivot = new Vector2(0.5f, 0.5f);
				val2.anchoredPosition = new Vector2(0f - horizontalInset, 0f);
				((Transform)val2).localScale = new Vector3(-1f, 1f, 1f);
			}
			else
			{
				val2.anchorMin = new Vector2(0f, 0.5f);
				val2.anchorMax = new Vector2(0f, 0.5f);
				val2.pivot = new Vector2(0.5f, 0.5f);
				val2.anchoredPosition = new Vector2(horizontalInset, 0f);
				((Transform)val2).localScale = Vector3.one;
			}
			val2.sizeDelta = capSize;
			Image val3 = val.AddComponent<Image>();
			val3.sprite = sprite;
			val3.type = (Type)0;
			((Graphic)val3).color = color;
			val3.preserveAspect = true;
			((Graphic)val3).raycastTarget = false;
		}

		internal static GameObject ReplaceStyledBackground(GameObject currentBackground, string objectName, GameObject parent, InfoRailBackgroundType backgroundType, Color backgroundColor, string vanillaSpriteName, LogManager specificLog)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)currentBackground != (Object)null)
			{
				Object.Destroy((Object)(object)currentBackground);
			}
			return CreateStyledBackground(objectName, parent, backgroundType, backgroundColor, vanillaSpriteName, specificLog);
		}

		internal static GameObject ReplaceStyledBorder(GameObject currentBorder, string objectName, GameObject parent, InfoRailBorderType borderType, string capSpriteName, Color borderColor, Vector2 capSize, Color borderOuterColor, Color borderInnerColor, float borderOuterWidth, float borderInnerWidth, LogManager specificLog)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)currentBorder != (Object)null)
			{
				Object.Destroy((Object)(object)currentBorder);
			}
			return CreateStyledBorder(objectName, parent, borderType, capSpriteName, borderColor, capSize, borderOuterColor, borderInnerColor, borderOuterWidth, borderInnerWidth, specificLog);
		}

		internal static GameObject CreateStyledBackground(string objectName, GameObject parent, InfoRailBackgroundType backgroundType, Color backgroundColor, string vanillaSpriteName, LogManager specificLog)
		{
			//IL_001f: 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)
			switch (backgroundType)
			{
			case InfoRailBackgroundType.None:
				return null;
			case InfoRailBackgroundType.UnityImage:
				return CreateUnityBackground(objectName, parent, backgroundColor);
			case InfoRailBackgroundType.VanillaSlicedSprite:
				return CreateVanillaSlicedBackground(objectName, parent, vanillaSpriteName, backgroundColor, specificLog);
			default:
				specificLog.Warn($"Unsupported information rail background type '{backgroundType}'.");
				return null;
			}
		}

		private static GameObject CreateUnityBackground(string objectName, GameObject parent, Color color)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateBackgroundObject(objectName, parent, 0);
			Image val2 = val.AddComponent<Image>();
			((Graphic)val2).color = color;
			((Graphic)val2).raycastTarget = false;
			return val;
		}

		private static GameObject CreateVanillaSlicedBackground(string objectName, GameObject parent, string spriteName, Color color, LogManager specificLog)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = CreateBackgroundObject(objectName, parent, 0);
			Sprite val2 = ((IEnumerable<Sprite>)Resources.FindObjectsOfTypeAll<Sprite>()).FirstOrDefault((Func<Sprite, bool>)((Sprite foundSprite) => ((Object)foundSprite).name == spriteName));
			if ((Object)(object)val2 == (Object)null)
			{
				specificLog.Warn("Could not find vanilla UI sprite '" + spriteName + "'.");
			}
			Image val3 = val.AddComponent<Image>();
			val3.sprite = val2;
			val3.type = (Type)1;
			((Graphic)val3).color = color;
			((Graphic)val3).raycastTarget = false;
			return val;
		}

		internal static GameObject CreateStyledBorder(string objectName, GameObject parent, InfoRailBorderType borderType, string capSpriteName, Color borderColor, Vector2 capSize, Color borderOuterColor, Color borderInnerColor, float borderOuterWidth, float borderInnerWidth, LogManager specificLog)
		{
			//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_0034: 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)
			switch (borderType)
			{
			case InfoRailBorderType.None:
				return null;
			case InfoRailBorderType.SideCapsSprite:
				return CreateSideCapsBorder(objectName, parent, capSpriteName, borderColor, capSize, specificLog);
			case InfoRailBorderType.UnityBorder:
				return CreateUnityBorder(objectName, parent, borderOuterColor, borderColor, borderInnerColor, borderOuterWidth, borderInnerWidth);
			default:
				specificLog.Warn($"Unsupported information rail border type '{borderType}'.");
				return null;
			}
		}

		private static GameObject CreateBackgroundObject(string objectName, GameObject parent, int siblingIndex)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0038: 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_0050: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(objectName);
			val.layer = 5;
			val.transform.SetParent(parent.transform, false);
			val.transform.SetSiblingIndex(siblingIndex);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			((Transform)val2).localScale = Vector3.one;
			LayoutElement val3 = val.AddComponent<LayoutElement>();
			val3.ignoreLayout = true;
			return val;
		}

		private static GameObject CreateUnityBorder(string objectName, GameObject parent, Color outerColor, Color mainColor, Color innerColor, float outerWidth, float innerWidth)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_0038: 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_0050: 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_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(objectName);
			val.layer = 5;
			val.transform.SetParent(parent.transform, false);
			val.transform.SetSiblingIndex(1);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			((Transform)val2).localScale = Vector3.one;
			LayoutElement val3 = val.AddComponent<LayoutElement>();
			val3.ignoreLayout = true;
			CreateUnityBorderLayer("Outer", val, outerColor, outerWidth, 0f);
			CreateUnityBorderLayer("Main", val, mainColor, 1f, 1f);
			CreateUnityBorderLayer("Inner", val, innerColor, innerWidth, 2f);
			return val;
		}

		private static void CreateUnityBorderLayer(string objectName, GameObject parent, Color color, float width, float inset)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0111: Unknown result type (might be due to invalid IL or missing references)
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: 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)
			GameObject val = new GameObject(objectName);
			val.layer = 5;
			val.transform.SetParent(parent.transform, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = Vector2.zero;
			val2.anchorMax = Vector2.one;
			val2.offsetMin = Vector2.zero;
			val2.offsetMax = Vector2.zero;
			((Transform)val2).localScale = Vector3.one;
			CreateUnityBorderLine("Top", val, color, new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(inset, 0f - inset - width), new Vector2(0f - inset, 0f - inset));
			CreateUnityBorderLine("Bottom", val, color, new Vector2(0f, 0f), new Vector2(1f, 0f), new Vector2(inset, inset), new Vector2(0f - inset, inset + width));
			CreateUnityBorderLine("Left", val, color, new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(inset, inset), new Vector2(inset + width, 0f - inset));
			CreateUnityBorderLine("Right", val, color, new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(0f - inset - width, inset), new Vector2(0f - inset, 0f - inset));
		}

		private static void CreateUnityBorderLine(string objectName, GameObject parent, Color color, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Expected O, but got Unknown
			//IL_002b: 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_003c: 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_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(objectName);
			val.layer = 5;
			val.transform.SetParent(parent.transform, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = anchorMin;
			val2.anchorMax = anchorMax;
			val2.offsetMin = offsetMin;
			val2.offsetMax = offsetMax;
			((Transform)val2).localScale = Vector3.one;
			Image val3 = val.AddComponent<Image>();
			((Graphic)val3).color = color;
			((Graphic)val3).raycastTarget = false;
		}

		protected static string CreateLabeledValue(string label, string value, Color valueColor)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			string text = ColorUtility.ToHtmlStringRGB(valueColor);
			return label + ": <color=#" + text + ">" + value + "</color>";
		}
	}
	internal class UIDetailedHovers
	{
		[HarmonyPatch(typeof(Container), "GetHoverText")]
		internal static class DetailedHoverContainer_Patch
		{
			private static void Postfix(Container __instance, Inventory ___m_inventory, ref string __result)
			{
				if (ConfigManager.EffectiveDetailedHoverInfoChoice != ConfigManager.HoverInfoMode.Off && HasContainerAccess(__instance) && ___m_inventory != null && ___m_inventory.NrOfItems() != 0)
				{
					__result = GetContainerHover(__instance, ___m_inventory);
				}
			}

			private static string GetContainerHover(Container container, Inventory inventory)
			{
				//IL_0060: 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_00c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_011a: Unknown result type (might be due to invalid IL or missing references)
				ConfigManager.ContainerHoverMode effectiveContainerHoverModeChoice = ConfigManager.EffectiveContainerHoverModeChoice;
				int num = inventory.GetWidth() * inventory.GetHeight();
				string text = "";
				switch (effectiveContainerHoverModeChoice)
				{
				case ConfigManager.ContainerHoverMode.CurrentPerMax:
				{
					int num3 = inventory.NrOfItems();
					string text4 = $"{num3}/{num}";
					text = PaintTextIfEnabled(text4, GetInventoryRatioColor(num3, num));
					break;
				}
				case ConfigManager.ContainerHoverMode.AmountOfFreeSlots:
				{
					int emptySlots = inventory.GetEmptySlots();
					string text3 = emptySlots.ToString();
					text = "Free Slots: " + PaintTextIfEnabled(text3, GetInventoryEmptySlotsColor(emptySlots, num));
					break;
				}
				case ConfigManager.ContainerHoverMode.Percent:
				{
					float num2 = inventory.SlotsUsedPercentage();
					float percent = num2 / 100f;
					string text2 = $"{num2}%";
					text = PaintTextIfEnabled(text2, GetPercentColorInverted(percent));
					break;
				}
				}
				string text5 = Localization.instance.Localize(container.m_name);
				string text6 = Localization.instance.Localize("$piece_container_open");
				string text7 = Localization.instance.Localize("$msg_stackall_hover");
				string text8 = "[" + PaintText(Localization.instance.Localize("$KEY_Use"), Color.yellow) + "]";
				string containerInventoryList = UIContainerContents.GetContainerInventoryList(container, inventory);
				return (containerInventoryList != "") ? (text5 + " (" + text + ")\n" + text8 + " " + text6 + " " + text7 + "\n\n" + containerInventoryList) : (text5 + " (" + text + ")\n" + text8 + " " + text6 + " " + text7);
			}

			private static Color GetInventoryRatioColor(int used, int max)
			{
				//IL_0038: 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_0049: 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_001f: 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_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				float num = ((max > 0) ? ((float)used / (float)max) : 0f);
				return (num < 0.5f) ? Color.Lerp(Color.green, Color.yellow, num / 0.5f) : Color.Lerp(Color.yellow, Color.red, (num - 0.5f) / 0.5f);
			}

			private static Color GetInventoryEmptySlotsColor(int empty, int max)
			{
				//IL_0038: 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_0049: 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_001f: 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_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				float num = ((max > 0) ? ((float)empty / (float)max) : 0f);
				return (num < 0.5f) ? Color.Lerp(Color.red, Color.yellow, num / 0.5f) : Color.Lerp(Color.yellow, Color.green, (num - 0.5f) / 0.5f);
			}
		}

		[HarmonyPatch(typeof(Beehive), "GetHoverText")]
		internal static class DetailedHoverBeehive_Patch
		{
			private static bool Prefix(Beehive __instance, ZNetView ___m_nview, ref string __result)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				if (ConfigManager.EffectiveDetailedHoverInfoChoice == ConfigManager.HoverInfoMode.Off)
				{
					return true;
				}
				if (!PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, false, false))
				{
					__result = Localization.instance.Localize(__instance.m_name + "\n$piece_noaccess");
					return false;
				}
				__result = GetBeehiveHover(__instance, ___m_nview);
				return false;
			}

			private static string GetBeehiveHover(Beehive beehive, ZNetView nview)
			{
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
				//IL_0119: Unknown result type (might be due to invalid IL or missing references)
				//IL_012c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0173: Unknown result type (might be due to invalid IL or missing references)
				//IL_0178: Unknown result type (might be due to invalid IL or missing references)
				//IL_017c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0197: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
				//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
				string text = Localization.instance.Localize(beehive.m_name);
				if (GetHoneyLevelMethod == null || ((nview != null) ? nview.GetZDO() : null) == null)
				{
					log.Warn("Beehive reflection methods not found.");
					return text;
				}
				int num = (int)GetHoneyLevelMethod.Invoke(beehive, null);
				float num2 = nview.GetZDO().GetFloat("product", 0f);
				float seconds = beehive.m_secPerUnit - num2;
				ConfigManager.BeeHoverMode effectiveBeehiveHoverModeChoice = ConfigManager.EffectiveBeehiveHoverModeChoice;
				string text2 = "";
				switch (effectiveBeehiveHoverModeChoice)
				{
				case ConfigManager.BeeHoverMode.Percent:
				{
					float num4 = Mathf.Clamp01(num2 / beehive.m_secPerUnit);
					text2 = PaintTextIfEnabled($"{num4:0%}", GetPercentColor(num4));
					break;
				}
				case ConfigManager.BeeHoverMode.RemainingTime:
					text2 = PaintTextIfEnabled(FormatTime(seconds), Color.cyan);
					break;
				case ConfigManager.BeeHoverMode.PercentAndTime:
				{
					float num3 = Mathf.Clamp01(num2 / beehive.m_secPerUnit);
					string text3 = PaintTextIfEnabled($"{num3:0%}", GetPercentColor(num3));
					string text4 = PaintTextIfEnabled(FormatTime(seconds), Color.cyan);
					text2 = text3 + " - " + text4;
					break;
				}
				}
				string text5 = Localization.instance.Localize(beehive.m_honeyItem.m_itemData.m_shared.m_name);
				Color honeyColor = GetHoneyColor(num, beehive.m_maxHoney);
				string text6 = PaintTextIfEnabled(text5, honeyColor);
				string text7 = PaintTextIfEnabled("x" + num, honeyColor);
				string text8 = "[" + PaintText(Localization.instance.Localize("$KEY_Use"), Color.yellow) + "]";
				if (num == beehive.m_maxHoney)
				{
					return text + " ( " + text6 + " " + text7 + " )\n" + text8 + " " + Localization.instance.Localize("$piece_beehive_extract");
				}
				if (num > 0)
				{
					return text + " ( " + text2 + ", " + text6 + " " + text7 + " )\n" + text8 + " " + Localization.instance.Localize("$piece_beehive_extract");
				}
				string text9 = PaintTextIfEnabled(Localization.instance.Localize("$piece_container_empty"), GetEmptyColor());
				return text + " ( " + text2 + ", " + text9 + " )\n" + text8 + " " + Localization.instance.Localize("$piece_beehive_check");
			}

			private static Color GetHoneyColor(int honeyLevel, int maxHoney)
			{
				//IL_0038: 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_0049: 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_001f: 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_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0051: Unknown result type (might be due to invalid IL or missing references)
				float num = ((maxHoney > 0) ? ((float)honeyLevel / (float)maxHoney) : 0f);
				return (num < 0.5f) ? Color.Lerp(Color.red, Color.yellow, num / 0.5f) : Color.Lerp(Color.yellow, Color.green, (num - 0.5f) / 0.5f);
			}

			private static Color GetEmptyColor()
			{
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//IL_0018: Unknown result type (might be due to invalid IL or missing references)
				return new Color(1f, 0.4f, 0f);
			}
		}

		[HarmonyPatch(typeof(Plant), "GetHoverText")]
		internal static class DetailedHoverPlant_Patch
		{
			private static bool Prefix(Plant __instance, ref string __result)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				if (ConfigManager.EffectiveDetailedHoverInfoChoice == ConfigManager.HoverInfoMode.Off)
				{
					return true;
				}
				if (!PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, false, false))
				{
					__result = Localization.instance.Localize(__instance.m_name + "\n$piece_noaccess");
					return false;
				}
				__result = GetPlantHover(__instance);
				return false;
			}

			private static string GetPlantHover(Plant plant)
			{
				//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0114: Unknown result type (might be due to invalid IL or missing references)
				//IL_0138: Unknown result type (might be due to invalid IL or missing references)
				//IL_016b: Unknown result type (might be due to invalid IL or missing references)
				string text = Localization.instance.Localize(plant.m_name);
				if (GetTimeSincePlantedMethod == null || GetGrowTimeMethod == null)
				{
					log.Warn("Plant reflection methods not found.");
					return text;
				}
				ConfigManager.PlantHoverMode effectivePlantHoverModeChoice = ConfigManager.EffectivePlantHoverModeChoice;
				double num = (double)GetTimeSincePlantedMethod.Invoke(plant, null);
				float num2 = (float)GetGrowTimeMethod.Invoke(plant, null);
				string text2 = "";
				switch (effectivePlantHoverModeChoice)
				{
				case ConfigManager.PlantHoverMode.Percent:
				{
					float num4 = Mathf.Clamp01((float)(num / (double)num2));
					text2 = PaintTextIfEnabled($"{num4:0%}", GetPercentColor(num4));
					break;
				}
				case ConfigManager.PlantHoverMode.RemainingTime:
				{
					float seconds2 = Mathf.Max(0f, num2 - (float)num);
					text2 = PaintTextIfEnabled(FormatTime(seconds2), Color.cyan);
					break;
				}
				case ConfigManager.PlantHoverMode.PercentAndTime:
				{
					float num3 = Mathf.Clamp01((float)(num / (double)num2));
					string text3 = PaintTextIfEnabled($"{num3:0%}", GetPercentColor(num3));
					float seconds = Mathf.Max(0f, num2 - (float)num);
					string text4 = PaintTextIfEnabled(FormatTime(seconds), Color.cyan);
					text2 = text3 + " - " + text4;
					break;
				}
				}
				string text5 = "[" + PaintText(Localization.instance.Localize("$KEY_Use"), Color.yellow) + "]";
				if (num >= (double)num2)
				{
					return text + " ( " + Localization.instance.Localize("$hud_ready") + " )\n" + text5 + " " + Localization.instance.Localize("$inventory_pickup");
				}
				return text + " ( " + text2 + " )";
			}
		}

		[HarmonyPatch(typeof(Fermenter), "GetHoverText")]
		internal static class DetailedHoverFermenter_Patch
		{
			private static bool Prefix(Fermenter __instance, bool ___m_exposed, ref string __result)
			{
				//IL_0017: Unknown result type (might be due to invalid IL or missing references)
				if (ConfigManager.EffectiveDetailedHoverInfoChoice == ConfigManager.HoverInfoMode.Off)
				{
					return true;
				}
				if (!PrivateArea.CheckAccess(((Component)__instance).transform.position, 0f, false, false))
				{
					__result = Localization.instance.Localize(__instance.m_name + "\n$piece_noaccess");
					return false;
				}
				string fermenterHover = GetFermenterHover(__instance, ___m_exposed);
				if (fermenterHover == null)
				{
					return true;
				}
				__result = fermenterHover;
				return false;
			}

			private static string GetFermenterHover(Fermenter fermenter, bool exposed)
			{
				//IL_02fa: Unknown result type (might be due to invalid IL or missing references)
				//IL_031f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0217: Unknown result type (might be due to invalid IL or missing references)
				//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
				//IL_0250: 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)
				string text = Localization.instance.Localize(fermenter.m_name);
				if (GetFermenterStatusMethod == null || GetFermenterContentNameMethod == null || GetFermentationTimeMethod == null)
				{
					log.Warn("Fermenter reflection methods not found.");
					return null;
				}
				object obj = GetFermenterStatusMethod.Invoke(fermenter, null);
				if (obj == null)
				{
					return null;
				}
				string name = Enum.GetName(GetFermenterStatusMethod.ReturnType, obj);
				string text2 = name;
				string text3 = text2;
				if (!(text3 == "Fermenting"))
				{
					if (text3 == "Ready")
					{
						string text4 = (string)GetFermenterContentNameMethod.Invoke(fermenter, null);
						string text5 = "[" + PaintText(Localization.instance.Localize("$KEY_Use"), Color.yellow) + "]";
						string text6 = PaintTextIfEnabled(Localization.instance.Localize("$piece_fermenter_ready"), Color.green);
						string text7 = Localization.instance.Localize("$piece_fermenter_tap");
						return Localization.instance.Localize(text + " ( " + text6 + " )\n" + text4 + "\n" + text5 + " " + text7);
					}
				}
				else
				{
					string text8 = Localization.instance.Localize((string)GetFermenterContentNameMethod.Invoke(fermenter, null));
					string text9 = Localization.instance.Localize("$piece_fermenter_exposed");
					string text10 = Localization.instance.Localize("$piece_fermenter_fermenting");
					if (exposed)
					{
						return text + " ( " + text8 + " )\n" + text9;
					}
					double num = (double)GetFermentationTimeMethod.Invoke(fermenter, null);
					float fermentationDuration = fermenter.m_fermentationDuration;
					switch (ConfigManager.EffectiveFermenterHoverModeChoice)
					{
					case ConfigManager.FermenterHoverMode.Percent:
					{
						float num3 = Mathf.Clamp01((float)(num / (double)fermentationDuration));
						return text + " ( " + text8 + " )\n" + text10 + ": " + PaintTextIfEnabled($"{num3:0%}", GetPercentColor(num3));
					}
					case ConfigManager.FermenterHoverMode.RemainingTime:
					{
						float seconds2 = Mathf.Max(0f, fermentationDuration - (float)num);
						return text + " ( " + text8 + " )\n" + text10 + ": " + PaintTextIfEnabled(FormatTime(seconds2), Color.cyan);
					}
					case ConfigManager.FermenterHoverMode.PercentAndTime:
					{
						float num2 = Mathf.Clamp01((float)(num / (double)fermentationDuration));
						string text11 = PaintTextIfEnabled($"{num2:0%}", GetPercentColor(num2));
						float seconds = Mathf.Max(0f, fermentationDuration - (float)num);
						string text12 = PaintTextIfEnabled(FormatTime(seconds), Color.cyan);
						return text + " ( " + text8 + " )\n" + text10 + ": " + text11 + " - " + text12;
					}
					}
				}
				return null;
			}
		}

		[HarmonyPatch(typeof(CookingStation), "Awake")]
		internal static class CookingStation_AddFoodSwitchHoverPatch
		{
			private static void Postfix(CookingStation __instance)
			{
				//IL_006d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0077: Expected O, but got Unknown
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00d9: Expected O, but got Unknown
				if ((Object)(object)__instance == (Object)null)
				{
					return;
				}
				if ((Object)(object)__instance.m_addFoodSwitch != (Object)null && __instance.m_addFoodSwitch.m_onHover == null && GetHoverTextMethod != null)
				{
					__instance.m_addFoodSwitch.m_onHover = (TooltipCallback)delegate
					{
						string text = Localization.instance.Localize(GetHoverTextMethod.Invoke(__instance, null) as string);
						if (ConfigManager.EffectiveDetailedHoverInfoChoice == ConfigManager.HoverInfoMode.Off)
						{
							return text;
						}
						string cookingStationHover = GetCookingStationHover(__instance);
						return (!string.IsNullOrEmpty(cookingStationHover)) ? cookingStationHover : text;
					};
				}
				if (!((Object)(object)__instance.m_addFuelSwitch != (Object)null) || __instance.m_addFuelSwitch.m_onHover != null || !(OnHoverFuelSwitchMethod != null) || !(GetCSFuelMethod != null))
				{
					return;
				}
				__instance.m_addFuelSwitch.m_onHover = (TooltipCallback)delegate
				{
					//IL_007d: Unknown result type (might be due to invalid IL or missing references)
					string text = Localization.instance.Localize(OnHoverFuelSwitchMethod.Invoke(__instance, null) as string);
					if (ConfigManager.EffectiveDetailedHoverInfoChoice == ConfigManager.HoverInfoMode.Off)
					{
						return text;
					}
					float num = (float)GetCSFuelMethod.Invoke(__instance, null);
					float num2 = num * (float)__instance.m_secPerFuel;
					return (num2 <= 0f) ? text : (text + "\nTime Left: " + PaintTextIfEnabled(FormatTime(num2), Color.cyan));
				};
			}
		}

		[HarmonyPatch(typeof(CookingStation), "GetHoverText")]
		internal static class CookingStationHoverPatch
		{
			private static bool Prefix(CookingStation __instance, ZNetView ___m_nview, ref string __result)
			{
				if (ConfigManager.EffectiveDetailedHoverInfoChoice == ConfigManager.HoverInfoMode.Off)
				{
					return true;
				}
				if ((Object)(object)___m_nview == (Object)null || !___m_nview.IsOwner())
				{
					return true;
				}
				if (__instance.m_useFuel && !__instance.m_requireFire)
				{
					return true;
				}
				string cookingStationHover = GetCookingStationHover(__instance);
				if (cookingStationHover == null)
				{
					return true;
				}
				__result = cookingStationHover;
				return false;
			}
		}

		[HarmonyPatch(typeof(Smelter), "OnHoverAddOre")]
		internal static class SmelterHoverAddPatch
		{
			private static void Postfix(Smelter __instance, ref string __result)
			{
				if (ConfigManager.EffectiveDetailedHoverInfoChoice != ConfigManager.HoverInfoMode.Off)
				{
					__result = GetSmelterHover(__instance, __result);
				}
			}
		}

		[HarmonyPatch(typeof(Smelter), "OnHoverAddFuel")]
		internal static class SmelterHoverFuelPatch
		{
			private static void Postfix(Smelter __instance, ref string __result)
			{
				if (ConfigManager.EffectiveDetailedHoverInfoChoice != ConfigManager.HoverInfoMode.Off)
				{
					__result = GetSmelterHover(__instance, __result);
				}
			}
		}

		[HarmonyPatch(typeof(Smelter), "OnHoverEmptyOre")]
		internal static class SmelterHoverEmptyPatch
		{
			private static void Postfix(Smelter __instance, ref string __result)
			{
				if (ConfigManager.EffectiveDetailedHoverInfoChoice != ConfigManager.HoverInfoMode.Off)
				{
					__result = GetSmelterHover(__instance, __result);
				}
			}
		}

		[HarmonyPatch(typeof(EggGrow), "GetHoverText")]
		internal static class EggGrowHoverPatch
		{
			private static void Postfix(EggGrow __instance, ZNetView ___m_nview, ref string __result)
			{
				if (ConfigManager.EffectiveDetailedHoverInfoChoice != ConfigManager.HoverInfoMode.Off)
				{
					__result = GetEggHover(__instance, ___m_nview, __result);
				}
			}

			private static string GetEggHover(EggGrow egg, ZNetView nview, string originalHover)
			{
				//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
				//IL_016a: Unknown result type (might be due to invalid IL or missing references)
				//IL_019b: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
				//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)nview == (Object)null || !nview.IsValid())
				{
					return originalHover;
				}
				ZDO zDO = nview.GetZDO();
				if (zDO == null)
				{
					return originalHover;
				}
				float num = zDO.GetFloat(ZDOVars.s_growStart, 0f);
				if (num <= 0f)
				{
					return originalHover;
				}
				double num2 = ZNet.instance.GetTimeSeconds() - (double)num;
				float growTime = egg.m_growTime;
				GameObject grownPrefab = egg.m_grownPrefab;
				object obj = ((grownPrefab == null) ? null : grownPrefab.GetComponent<Character>()?.m_name);
				if (obj == null)
				{
					GameObject grownPrefab2 = egg.m_grownPrefab;
					obj = ((grownPrefab2 != null) ? ((Object)grownPrefab2).name : null) ?? "Unknown";
				}
				string text = (string)obj;
				text = Localization.instance.Localize(text);
				if (num2 >= (double)growTime)
				{
					return originalHover + "\n" + text + ": " + PaintTextIfEnabled("Hatching soon", Color.green);
				}
				float num3 = Mathf.Clamp01((float)(num2 / (double)growTime));
				float seconds = Mathf.Max(0f, g