Decompiled source of BetterUI v1.0.24

BetterUI.dll

Decompiled 3 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("BetterUI")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BetterUI")]
[assembly: AssemblyTitle("BetterUI")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace BetterUI
{
	[BepInPlugin("zenox.betterui", "BetterUI", "1.0.24")]
	public class BetterUIPlugin : BaseUnityPlugin
	{
		[HarmonyPatch(typeof(Hud), "Awake")]
		private static class Hud_Awake_XPBar_Patch
		{
			private static void Postfix(Hud __instance)
			{
				//IL_0084: 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_00a4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
				//IL_00df: 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_0109: 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_012a: Unknown result type (might be due to invalid IL or missing references)
				//IL_012f: Unknown result type (might be due to invalid IL or missing references)
				//IL_013c: Unknown result type (might be due to invalid IL or missing references)
				//IL_015c: Unknown result type (might be due to invalid IL or missing references)
				if (!CharacterXPEnabled.Value || (Object)(object)xpBar != (Object)null)
				{
					return;
				}
				Transform val = Utils.FindChild(((Component)__instance).gameObject.transform, "hudroot", (IterativeSearchType)0);
				if (!((Object)(object)val == (Object)null) && !((Object)(object)__instance.m_stealthBar == (Object)null))
				{
					GuiBar obj = Object.Instantiate<GuiBar>(__instance.m_stealthBar, val, true);
					((Object)obj).name = "ZenoxCharacterXPBar";
					obj.SetMaxValue(1f);
					obj.SetValue(0f);
					Transform transform = ((Component)obj).transform;
					RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
					val2.anchorMin = Vector2.zero;
					val2.anchorMax = new Vector2(1f, 0f);
					val2.anchoredPosition = Vector2.zero;
					val2.offsetMin = Vector2.zero;
					val2.offsetMax = Vector2.zero;
					val2.sizeDelta = new Vector2(0f, 9f);
					obj.m_bar.anchorMin = Vector2.zero;
					obj.m_bar.anchorMax = new Vector2(1f, 0.5f);
					obj.m_bar.offsetMin = Vector2.zero;
					obj.m_bar.offsetMax = Vector2.zero;
					RectTransform bar = obj.m_bar;
					Rect rect = val2.rect;
					bar.sizeDelta = new Vector2(((Rect)(ref rect)).width, 9f);
					Image component = ((Component)obj.m_bar).GetComponent<Image>();
					if ((Object)(object)component != (Object)null)
					{
						((Graphic)component).color = Color.yellow;
					}
					((Component)obj).gameObject.SetActive(true);
					xpBar = obj;
				}
			}
		}

		[HarmonyPatch(typeof(Hud), "Update")]
		private static class Hud_Update_XPBar_Patch
		{
			private static void Postfix()
			{
				if (!CharacterXPEnabled.Value)
				{
					return;
				}
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer == (Object)null) && (Object)(object)xpPlayer == (Object)null)
				{
					XP_Awake(localPlayer);
					GuiBar xpBar = BetterUIPlugin.xpBar;
					if (xpBar != null)
					{
						xpBar.SetValue(XP_GetLevelPercentage());
					}
				}
			}
		}

		[HarmonyPatch(typeof(Skill), "Raise")]
		private static class SkillsSkill_Raise_XPBar_Patch
		{
			private static void Postfix(float factor)
			{
				if (CharacterXPEnabled.Value && !((Object)(object)xpBar == (Object)null) && !((Object)(object)xpPlayer == (Object)null))
				{
					XP_RaiseXP();
					xpBar.SetValue(XP_GetLevelPercentage());
				}
			}
		}

		[HarmonyPatch(typeof(FejdStartup), "UpdateCharacterList")]
		private static class FejdStartup_UpdateCharacterList_Stats_Patch
		{
			private static void Postfix(List<PlayerProfile> ___m_profiles, int ___m_profileIndex, FejdStartup __instance)
			{
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				//IL_0083: 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)
				if (ShowCharacterSelectStats.Value && ___m_profiles != null && ___m_profileIndex >= 0 && ___m_profileIndex < ___m_profiles.Count && !((Object)(object)__instance.m_csName == (Object)null) && ((Component)__instance.m_csName).gameObject.activeSelf)
				{
					RectTransform rectTransform = __instance.m_csName.rectTransform;
					if (float.IsNaN(csNameBaseY))
					{
						csNameBaseY = rectTransform.anchoredPosition.y;
					}
					rectTransform.anchoredPosition = new Vector2(rectTransform.anchoredPosition.x, csNameBaseY + CharacterSelectStatsYOffset.Value);
					PlayerProfile obj = ___m_profiles[___m_profileIndex];
					int num = (int)obj.m_playerStats[0][(PlayerStatType)6];
					int num2 = (int)obj.m_playerStats[0][(PlayerStatType)0];
					int num3 = (int)obj.m_playerStats[0][(PlayerStatType)1];
					int num4 = (int)obj.m_playerStats[0][(PlayerStatType)2];
					TMP_Text csName = __instance.m_csName;
					csName.text += $"\n<size={CharacterSelectStatsFontSize.Value}>Kills: {num}   Deaths: {num2}   Crafts: {num3}   Builds: {num4}</size>";
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGui), "UpdateCharacterStats")]
		private static class InventoryGui_UpdateCharacterStats_CombinedStats_Patch
		{
			private static void Postfix(InventoryGui __instance, Player player)
			{
				if (ShowCombinedItemStats.Value && !((Object)(object)player == (Object)null) && !((Object)(object)__instance.m_armor == (Object)null) && (!((Object)(object)combinedStatsTooltip == (Object)null) || TryCreateOverlay(__instance)))
				{
					statsBuilder.Clear();
					AppendWeaponStats(player, statsBuilder);
					AppendBlockStats(player, statsBuilder);
					statsBuilder.AppendFormat("\n\n$item_armor: <color=orange>{0}</color>", Mathf.RoundToInt(((Character)player).GetBodyArmor()));
					float equipmentMovementModifier = ((Character)player).GetEquipmentMovementModifier();
					if (equipmentMovementModifier != 0f)
					{
						string arg = ((equipmentMovementModifier > 0f) ? "green" : "red");
						statsBuilder.AppendFormat("\n$item_movement_modifier: <color={0}>{1:+0;-0}%</color>", arg, equipmentMovementModifier * 100f);
					}
					combinedStatsTooltip.m_text = Localization.instance.Localize(statsBuilder.ToString());
					combinedStatsTooltip.m_topic = $"Lv.{CharacterLevel} {player.GetPlayerName()}";
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
		private static class InventoryGrid_UpdateGui_DurabilityColor_Patch
		{
			private static void Postfix(List<InventoryElement> ___m_elements, Inventory ___m_inventory)
			{
				//IL_004e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0059: Unknown result type (might be due to invalid IL or missing references)
				if (!DurabilityColorEnabled.Value || ___m_inventory == null || ___m_elements == null)
				{
					return;
				}
				foreach (InventoryElement ___m_element in ___m_elements)
				{
					if (___m_element.m_used && !((Object)(object)___m_element.m_durability == (Object)null) && ((Component)___m_element.m_durability).gameObject.activeSelf)
					{
						ItemData itemAt = ___m_inventory.GetItemAt(___m_element.Position.x, ___m_element.Position.y);
						if (itemAt != null && itemAt.m_shared.m_useDurability && !(itemAt.m_durability <= 0f))
						{
							ApplyDurabilityColor(___m_element.m_durability, itemAt.GetDurabilityPercentage());
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(HotkeyBar), "UpdateIcons")]
		private static class HotkeyBar_UpdateIcons_DurabilityColor_Patch
		{
			private static void Postfix(IList ___m_elements, List<ItemData> ___m_items)
			{
				if (!DurabilityColorEnabled.Value || ___m_elements == null || ___m_items == null)
				{
					return;
				}
				foreach (ItemData ___m_item in ___m_items)
				{
					int x = ___m_item.m_gridPos.x;
					if (x < 0 || x >= ___m_elements.Count || !___m_item.m_shared.m_useDurability || ___m_item.m_durability <= 0f)
					{
						continue;
					}
					object obj = ___m_elements[x];
					if (obj != null)
					{
						if (hotkeyDurabilityField == null || hotkeyDurabilityField.DeclaringType != obj.GetType())
						{
							hotkeyDurabilityField = AccessTools.Field(obj.GetType(), "m_durability");
						}
						object? obj2 = hotkeyDurabilityField?.GetValue(obj);
						GuiBar val = (GuiBar)((obj2 is GuiBar) ? obj2 : null);
						if (val != null && ((Component)val).gameObject.activeSelf)
						{
							ApplyDurabilityColor(val, ___m_item.GetDurabilityPercentage());
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(EnemyHud), "Awake")]
		private static class EnemyHud_Awake_DistanceMultiplier_Patch
		{
			private static void Postfix(EnemyHud __instance)
			{
				float num = Mathf.Clamp(EnemyHudDistanceMultiplier.Value, 0.1f, 5f);
				__instance.m_maxShowDistance *= num;
				__instance.m_maxShowDistanceBoss *= num;
			}
		}

		[HarmonyPatch(typeof(EnemyHud), "UpdateHuds")]
		private static class EnemyHud_UpdateHuds_AlwaysShowDistance_Patch
		{
			private static void Prefix(EnemyHud __instance)
			{
				//IL_003e: 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_0125: Unknown result type (might be due to invalid IL or missing references)
				//IL_012a: Unknown result type (might be due to invalid IL or missing references)
				//IL_012b: 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)
				if (EnemyUIAlwaysShowDistance.Value <= 0f || (Object)(object)Player.m_localPlayer == (Object)null)
				{
					return;
				}
				IDictionary dictionary = (IDictionary)HudsField.GetValue(__instance);
				if (dictionary == null)
				{
					return;
				}
				Vector3 position = ((Component)Player.m_localPlayer).transform.position;
				float num = EnemyUIAlwaysShowDistance.Value * EnemyUIAlwaysShowDistance.Value;
				int num2 = 0;
				foreach (DictionaryEntry item in dictionary)
				{
					object value = item.Value;
					if (value == null)
					{
						continue;
					}
					if (hudDataHoverTimerField == null || hudDataHoverTimerField.DeclaringType != value.GetType())
					{
						hudDataCharacterField = AccessTools.Field(value.GetType(), "m_character");
						hudDataHoverTimerField = AccessTools.Field(value.GetType(), "m_hoverTimer");
					}
					object? obj = hudDataCharacterField?.GetValue(value);
					Character val = (Character)(((obj is Character) ? obj : null) ?? ((object)/*isinst with value type is only supported in some contexts*/));
					if (!((Object)(object)val == (Object)null) && !val.IsPlayer() && !val.IsBoss())
					{
						Vector3 val2 = ((Component)val).transform.position - position;
						if (!(((Vector3)(ref val2)).sqrMagnitude > num))
						{
							hudDataHoverTimerField?.SetValue(value, 0f);
							num2++;
						}
					}
				}
				if (!loggedAlwaysShowOnce && num2 > 0)
				{
					loggedAlwaysShowOnce = true;
					BetterUIPlugin instance = Instance;
					if (instance != null)
					{
						((BaseUnityPlugin)instance).Logger.LogInfo((object)$"[BetterUI] EnemyUIAlwaysShowDistance active: {num2} enemy hud(s) kept visible within {EnemyUIAlwaysShowDistance.Value}m this frame.");
					}
				}
			}
		}

		[HarmonyPatch(typeof(EnemyHud), "LateUpdate")]
		private static class EnemyHud_LateUpdate_LevelPrefix_Patch
		{
			private static void Postfix(EnemyHud __instance)
			{
				//IL_013f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0171: Unknown result type (might be due to invalid IL or missing references)
				//IL_0176: Unknown result type (might be due to invalid IL or missing references)
				//IL_017f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0193: Unknown result type (might be due to invalid IL or missing references)
				//IL_0241: Unknown result type (might be due to invalid IL or missing references)
				//IL_0485: Unknown result type (might be due to invalid IL or missing references)
				//IL_0493: Unknown result type (might be due to invalid IL or missing references)
				//IL_04a1: Unknown result type (might be due to invalid IL or missing references)
				//IL_04af: Unknown result type (might be due to invalid IL or missing references)
				//IL_03af: Unknown result type (might be due to invalid IL or missing references)
				//IL_03a8: Unknown result type (might be due to invalid IL or missing references)
				//IL_03a1: Unknown result type (might be due to invalid IL or missing references)
				IDictionary dictionary = (IDictionary)HudsField.GetValue(__instance);
				if (dictionary == null)
				{
					return;
				}
				Image val6 = default(Image);
				Image val8 = default(Image);
				foreach (DictionaryEntry item in dictionary)
				{
					object value = item.Value;
					if (value == null)
					{
						continue;
					}
					if (hudDataNameField == null || hudDataNameField.DeclaringType != value.GetType())
					{
						hudDataNameField = AccessTools.Field(value.GetType(), "m_name");
						hudDataCharacterField = AccessTools.Field(value.GetType(), "m_character");
						hudDataLevel2Field = AccessTools.Field(value.GetType(), "m_level2");
						hudDataLevel3Field = AccessTools.Field(value.GetType(), "m_level3");
						hudDataHealthFastField = AccessTools.Field(value.GetType(), "m_healthFast");
					}
					if (hudDataNameField == null)
					{
						break;
					}
					object? value2 = hudDataNameField.GetValue(value);
					TextMeshProUGUI val = (TextMeshProUGUI)((value2 is TextMeshProUGUI) ? value2 : null);
					if (val == null)
					{
						continue;
					}
					object? obj = hudDataCharacterField?.GetValue(value);
					Character val2 = (Character)(((obj is Character) ? obj : null) ?? ((object)/*isinst with value type is only supported in some contexts*/));
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					if (!enemyNameBaseY.TryGetValue(value, out var value3))
					{
						value3 = ((TMP_Text)val).rectTransform.anchoredPosition.y;
						enemyNameBaseY[value] = value3;
					}
					if (!val2.IsPlayer() && !val2.IsBoss())
					{
						Vector2 anchoredPosition = ((TMP_Text)val).rectTransform.anchoredPosition;
						((TMP_Text)val).rectTransform.anchoredPosition = new Vector2(anchoredPosition.x, value3 + EnemyNameYOffset.Value);
					}
					Transform val3 = null;
					if (!val2.IsPlayer())
					{
						object? obj2 = hudDataHealthFastField?.GetValue(value);
						GuiBar val4 = (GuiBar)((obj2 is GuiBar) ? obj2 : null);
						if (val4 != null && (Object)(object)val4 != (Object)null)
						{
							val3 = ((Component)val4).transform.parent;
							if ((Object)(object)val3 != (Object)null)
							{
								if (!val2.IsBoss())
								{
									float num = Mathf.Clamp(EnemyHealthBarScale.Value, 0.5f, 3f);
									float num2 = num * Mathf.Clamp(EnemyHealthBarHeightScale.Value, 0.5f, 3f);
									val3.localScale = new Vector3(num, num2, 1f);
								}
								if (HideEnemyBarBackground.Value)
								{
									Transform val5 = val3.Find("darken");
									if ((Object)(object)val5 != (Object)null && ((Component)val5).TryGetComponent<Image>(ref val6))
									{
										((Behaviour)val6).enabled = false;
									}
									Transform val7 = val3.Find("bkg");
									if ((Object)(object)val7 != (Object)null && ((Component)val7).TryGetComponent<Image>(ref val8))
									{
										((Behaviour)val8).enabled = false;
									}
								}
							}
						}
					}
					int value4 = EnemyLevelStyle.Value;
					if (!val2.IsPlayer() && !val2.IsBoss())
					{
						int num3 = Mathf.Max(0, val2.GetLevel() - 1);
						((TMP_Text)val).text = ((value4 == 0 || num3 == 0) ? val2.GetHoverName() : ("<color=#ffdb3c>" + StarText(num3) + "</color> " + val2.GetHoverName()));
						if (value4 == 1)
						{
							object? obj3 = hudDataLevel2Field?.GetValue(value);
							SetActiveIfPresent((RectTransform)((obj3 is RectTransform) ? obj3 : null), active: false);
							object? obj4 = hudDataLevel3Field?.GetValue(value);
							SetActiveIfPresent((RectTransform)((obj4 is RectTransform) ? obj4 : null), active: false);
						}
						if (ColorEnemyNameByAlertState.Value)
						{
							BaseAI baseAI = val2.GetBaseAI();
							bool flag = (Object)(object)baseAI != (Object)null && baseAI.IsAlerted();
							bool flag2 = (Object)(object)baseAI != (Object)null && baseAI.HaveTarget();
							((Graphic)val).color = (flag ? Color.red : (flag2 ? Color.yellow : Color.white));
						}
					}
					TMP_Text value5;
					if (ShowEnemyHpText.Value && !val2.IsPlayer() && (Object)(object)val3 != (Object)null)
					{
						TMP_Text orCreateHpLabel = GetOrCreateHpLabel(value, val);
						int num4 = (val2.IsBoss() ? BossHpTextFontSize.Value : EnemyHpTextFontSize.Value);
						orCreateHpLabel.text = $"<size={num4}>{Mathf.CeilToInt(val2.GetHealth())}/{Mathf.CeilToInt(val2.GetMaxHealth())}</size>";
						RectTransform val9 = (RectTransform)(object)((val3 is RectTransform) ? val3 : null);
						RectTransform rectTransform = orCreateHpLabel.rectTransform;
						if ((Object)(object)((Transform)rectTransform).parent != (Object)(object)val3.parent)
						{
							((Transform)rectTransform).SetParent(val3.parent, false);
						}
						if ((Object)(object)val9 != (Object)null)
						{
							rectTransform.anchorMin = val9.anchorMin;
							rectTransform.anchorMax = val9.anchorMax;
							rectTransform.pivot = val9.pivot;
							rectTransform.anchoredPosition = val9.anchoredPosition;
						}
					}
					else if (enemyHpLabels.TryGetValue(value, out value5) && (Object)(object)value5 != (Object)null)
					{
						((Component)value5).gameObject.SetActive(false);
					}
				}
			}
		}

		[HarmonyPatch(typeof(Container), "GetHoverText")]
		private static class Container_GetHoverText_Style_Patch
		{
			private static void Postfix(Container __instance, ref string __result)
			{
				if (HoverTextExtensionsEnabled.Value && ContainerHoverStyle.Value != 0 && !string.IsNullOrEmpty(__result))
				{
					Inventory inventory = __instance.GetInventory();
					if (inventory != null && inventory.NrOfItems() != 0)
					{
						__result = string.Concat(str2: ContainerHoverStyle.Value switch
						{
							1 => $"{inventory.SlotsUsedPercentage():F0}%", 
							2 => $"{inventory.NrOfItems()}/{inventory.GetWidth() * inventory.GetHeight()}", 
							_ => $"{inventory.GetEmptySlots()} free", 
						}, str0: __result, str1: " ( ", str3: " )");
					}
				}
			}
		}

		[HarmonyPatch(typeof(Fermenter), "GetHoverText")]
		private static class Fermenter_GetHoverText_TimeLeft_Patch
		{
			private static void Postfix(Fermenter __instance, ZNetView ___m_nview, ref string __result)
			{
				if (!HoverTextExtensionsEnabled.Value || FermenterHoverStyle.Value == 0 || string.IsNullOrEmpty(__result) || (Object)(object)___m_nview == (Object)null || !___m_nview.IsValid())
				{
					return;
				}
				long num = ___m_nview.GetZDO().GetLong(ZDOVars.s_startTime, 0L);
				if (num != 0L)
				{
					double totalSeconds = (ZNet.instance.GetTime() - new DateTime(num)).TotalSeconds;
					double num2 = (double)__instance.m_fermentationDuration - totalSeconds;
					if (!(num2 <= 0.0))
					{
						string text = ((FermenterHoverStyle.Value == 1) ? $"{totalSeconds / (double)__instance.m_fermentationDuration:P0} done" : (FormatDuration(num2) + " remaining"));
						__result = __result + "\n" + text;
					}
				}
			}
		}

		[HarmonyPatch(typeof(Plant), "GetHoverText")]
		private static class Plant_GetHoverText_TimeLeft_Patch
		{
			private static void Postfix(Plant __instance, ref string __result)
			{
				if (!HoverTextExtensionsEnabled.Value || !PlantGrowTimeHover.Value || string.IsNullOrEmpty(__result) || plantGrowTimeMethod == null || plantTimeSincePlantedMethod == null)
				{
					return;
				}
				try
				{
					double num = (double)(float)plantGrowTimeMethod.Invoke(__instance, null) - (double)plantTimeSincePlantedMethod.Invoke(__instance, null);
					if (num > 0.0)
					{
						__result = __result + "\n" + FormatDuration(num) + " until grown";
					}
				}
				catch (Exception)
				{
				}
			}
		}

		[HarmonyPatch(typeof(CookingStation), "GetHoverText")]
		private static class CookingStation_GetHoverText_Style_Patch
		{
			private static void Postfix(CookingStation __instance, ref string __result)
			{
				if (!HoverTextExtensionsEnabled.Value || CookingStationHoverStyle.Value == 0)
				{
					return;
				}
				if ((object)cookingStationNviewField == null)
				{
					cookingStationNviewField = AccessTools.Field(typeof(CookingStation), "m_nview");
				}
				if ((object)cookingStationGetSlotMethod == null)
				{
					cookingStationGetSlotMethod = AccessTools.Method(typeof(CookingStation), "GetSlot", (Type[])null, (Type[])null);
				}
				if ((object)cookingStationGetItemConversionMethod == null)
				{
					cookingStationGetItemConversionMethod = AccessTools.Method(typeof(CookingStation), "GetItemConversion", (Type[])null, (Type[])null);
				}
				if ((object)cookingStationIsFireLitMethod == null)
				{
					cookingStationIsFireLitMethod = AccessTools.Method(typeof(CookingStation), "IsFireLit", (Type[])null, (Type[])null);
				}
				if (cookingStationNviewField == null || cookingStationGetSlotMethod == null || cookingStationGetItemConversionMethod == null || cookingStationIsFireLitMethod == null)
				{
					return;
				}
				object? value = cookingStationNviewField.GetValue(__instance);
				ZNetView val = (ZNetView)((value is ZNetView) ? value : null);
				if (val == null || !val.IsValid() || !val.IsOwner())
				{
					return;
				}
				bool flag;
				try
				{
					flag = (bool)cookingStationIsFireLitMethod.Invoke(__instance, null);
				}
				catch (Exception)
				{
					return;
				}
				if (!flag)
				{
					return;
				}
				string text = "";
				int num = 0;
				for (int i = 0; i < __instance.m_slots.Length; i++)
				{
					object[] array = new object[5] { i, null, null, null, null };
					cookingStationGetSlotMethod.Invoke(__instance, array);
					string text2 = array[1] as string;
					if (string.IsNullOrEmpty(text2) || text2 == ((Object)__instance.m_overCookedItem).name)
					{
						continue;
					}
					object? obj = cookingStationGetItemConversionMethod.Invoke(__instance, new object[1] { text2 });
					ItemConversion val2 = (ItemConversion)((obj is ItemConversion) ? obj : null);
					if (val2 != null)
					{
						num++;
						float num2 = (float)array[2];
						if (num2 > val2.m_cookTime)
						{
							float num3 = val2.m_cookTime * 2f;
							string text3 = ((CookingStationHoverStyle.Value == 1) ? $"{num2 / num3:P0}" : FormatDuration(num3 - num2));
							text = text + "\n" + __instance.m_overCookedItem.GetHoverName() + ": <color=red>" + text3 + "</color>";
						}
						else
						{
							string text4 = ((CookingStationHoverStyle.Value == 1) ? $"{num2 / val2.m_cookTime:P0}" : FormatDuration(val2.m_cookTime - num2));
							text = text + "\n" + val2.m_to.GetHoverName() + ": " + text4;
						}
					}
				}
				if (num > 0)
				{
					__result = Localization.instance.Localize(__instance.m_name + text);
				}
			}
		}

		private class BarOffset
		{
			public ConfigEntry<bool> Enabled;

			public ConfigEntry<float> OffsetX;

			public ConfigEntry<float> OffsetY;

			public ConfigEntry<float> Scale;

			public Vector2[] BaseAnchoredPositions;

			public Vector3[] BaseScales;

			public bool Captured;
		}

		[HarmonyPatch(typeof(HotkeyBar), "Update")]
		private static class HotkeyBar_Update_CacheInstance_HudEditor_Patch
		{
			private static void Postfix(HotkeyBar __instance)
			{
				if (((Object)__instance).name == "HotKeyBar")
				{
					cachedHotkeyBar = __instance;
				}
			}
		}

		[HarmonyPatch(typeof(GameCamera), "UpdateMouseCapture")]
		private static class GameCamera_UpdateMouseCapture_HudEditor_Patch
		{
			private static void Postfix()
			{
				if ((Object)(object)Instance != (Object)null && Instance.editModeActive)
				{
					Cursor.lockState = (CursorLockMode)0;
					Cursor.visible = true;
				}
			}
		}

		[HarmonyPatch(typeof(PlayerController), "TakeInput", new Type[] { typeof(bool) })]
		private static class PlayerController_TakeInput_HudEditor_Patch
		{
			private static void Postfix(ref bool __result)
			{
				if ((Object)(object)Instance != (Object)null && Instance.editModeActive)
				{
					__result = false;
				}
			}
		}

		[HarmonyPatch(typeof(Hud), "Update")]
		private static class Hud_Update_ForceBarsVisible_HudEditor_Patch
		{
			private static readonly string[] FightingBars = new string[3] { "StaminaBar", "EitrBar", "AdrenalineBar" };

			private static bool forcedGpActive;

			public static void RestoreForcedActiveStates()
			{
				Hud instance = Hud.instance;
				if (!((Object)(object)instance == (Object)null))
				{
					if (forcedGpActive && (Object)(object)instance.m_gpRoot != (Object)null)
					{
						((Component)instance.m_gpRoot).gameObject.SetActive(false);
					}
					forcedGpActive = false;
				}
			}

			private static void Postfix(Hud __instance)
			{
				//IL_010b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0126: Unknown result type (might be due to invalid IL or missing references)
				//IL_012b: Unknown result type (might be due to invalid IL or missing references)
				//IL_013e: Unknown result type (might be due to invalid IL or missing references)
				//IL_014e: Unknown result type (might be due to invalid IL or missing references)
				if ((Object)(object)Instance == (Object)null || !Instance.editModeActive)
				{
					return;
				}
				if ((Object)(object)__instance.m_staminaAnimator != (Object)null)
				{
					__instance.m_staminaAnimator.SetBool("Visible", true);
				}
				if ((Object)(object)__instance.m_eitrAnimator != (Object)null)
				{
					__instance.m_eitrAnimator.SetBool("Visible", true);
				}
				if ((Object)(object)__instance.m_adrenalineAnimator != (Object)null)
				{
					__instance.m_adrenalineAnimator.SetBool("Visible", true);
				}
				if ((Object)(object)__instance.m_gpRoot != (Object)null && !((Component)__instance.m_gpRoot).gameObject.activeSelf)
				{
					((Component)__instance.m_gpRoot).gameObject.SetActive(true);
					forcedGpActive = true;
				}
				string[] fightingBars = FightingBars;
				foreach (string text in fightingBars)
				{
					if (Instance.barOffsets.TryGetValue(text, out var value) && value.Captured && value.Enabled.Value)
					{
						RectTransform barRoot = Instance.GetBarRoot(text);
						if (!((Object)(object)barRoot == (Object)null))
						{
							barRoot.anchoredPosition = value.BaseAnchoredPositions[0] + new Vector2(value.OffsetX.Value, value.OffsetY.Value);
							((Transform)barRoot).localScale = value.BaseScales[0] * value.Scale.Value;
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(ZInput), "GetMouseScrollWheel")]
		private static class ZInput_GetMouseScrollWheel_HudEditor_Patch
		{
			private static void Postfix(ref float __result)
			{
				if ((Object)(object)Instance != (Object)null && Instance.editModeActive)
				{
					__result = 0f;
				}
			}
		}

		[HarmonyPatch(typeof(InventoryGrid), "UpdateGui")]
		private static class InventoryGrid_UpdateGui_ItemLevelStars_Patch
		{
			private static void Postfix(List<InventoryElement> ___m_elements, Inventory ___m_inventory)
			{
				//IL_0045: 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_00a9: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
				if (!ItemLevelStarsEnabled.Value || ___m_inventory == null || ___m_elements == null)
				{
					return;
				}
				foreach (InventoryElement ___m_element in ___m_elements)
				{
					if (___m_element.m_used && !((Object)(object)___m_element.m_quality == (Object)null))
					{
						ItemData itemAt = ___m_inventory.GetItemAt(___m_element.Position.x, ___m_element.Position.y);
						if (itemAt != null && itemAt.m_shared.m_maxQuality > 1)
						{
							___m_element.m_quality.text = $"<size={InventoryStarFontSize.Value}>{StarText(itemAt.m_quality)}</size>";
							((Graphic)___m_element.m_quality).color = StarColor;
							___m_element.m_quality.enableWordWrapping = false;
							___m_element.m_quality.rectTransform.sizeDelta = new Vector2((float)itemAt.m_quality * ((float)InventoryStarFontSize.Value * 0.85f), 20f);
						}
					}
				}
			}
		}

		[HarmonyPatch(typeof(HotkeyBar), "UpdateIcons")]
		private static class HotkeyBar_UpdateIcons_ItemLevelStars_Patch
		{
			private static void Postfix(IList ___m_elements, List<ItemData> ___m_items)
			{
				//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
				if (!HotbarStarsEnabled.Value)
				{
					foreach (TMP_Text value3 in hotkeyStarLabels.Values)
					{
						if ((Object)(object)value3 != (Object)null)
						{
							((Component)value3).gameObject.SetActive(false);
						}
					}
					return;
				}
				if (___m_elements == null || ___m_items == null)
				{
					return;
				}
				HashSet<int> hashSet = new HashSet<int>();
				foreach (ItemData ___m_item in ___m_items)
				{
					int x = ___m_item.m_gridPos.x;
					if (x < 0 || x >= ___m_elements.Count)
					{
						continue;
					}
					object obj = ___m_elements[x];
					if (obj == null)
					{
						continue;
					}
					if (hotkeyGoField == null || hotkeyGoField.DeclaringType != obj.GetType())
					{
						hotkeyGoField = AccessTools.Field(obj.GetType(), "m_go");
					}
					object? obj2 = hotkeyGoField?.GetValue(obj);
					GameObject val = (GameObject)((obj2 is GameObject) ? obj2 : null);
					if (val == null)
					{
						continue;
					}
					Transform obj3 = val.transform.Find("binding");
					TMP_Text val2 = ((obj3 != null) ? ((Component)obj3).GetComponent<TMP_Text>() : null);
					if ((Object)(object)val2 == (Object)null)
					{
						continue;
					}
					hashSet.Add(x);
					if (___m_item.m_shared.m_maxQuality <= 1)
					{
						if (hotkeyStarLabels.TryGetValue(obj, out var value) && (Object)(object)value != (Object)null)
						{
							((Component)value).gameObject.SetActive(false);
						}
						continue;
					}
					TMP_Text orCreateHotkeyStarLabel = GetOrCreateHotkeyStarLabel(obj, val2);
					((Component)orCreateHotkeyStarLabel).gameObject.SetActive(true);
					orCreateHotkeyStarLabel.fontSize = HotbarStarFontSize.Value;
					orCreateHotkeyStarLabel.text = StarText(___m_item.m_quality);
					((Graphic)orCreateHotkeyStarLabel).color = StarColor;
					LogVisibilityChangeDiagnostic(orCreateHotkeyStarLabel);
				}
				for (int i = 0; i < ___m_elements.Count; i++)
				{
					if (!hashSet.Contains(i) && ___m_elements[i] != null && hotkeyStarLabels.TryGetValue(___m_elements[i], out var value2) && (Object)(object)value2 != (Object)null)
					{
						((Component)value2).gameObject.SetActive(false);
					}
				}
			}
		}

		private readonly struct PartyStatsSnapshot
		{
			public readonly float Health;

			public readonly float MaxHealth;

			public readonly float Stamina;

			public readonly float MaxStamina;

			public readonly float ReceivedAtTime;

			public PartyStatsSnapshot(float health, float maxHealth, float stamina, float maxStamina)
			{
				Health = health;
				MaxHealth = maxHealth;
				Stamina = stamina;
				MaxStamina = maxStamina;
				ReceivedAtTime = Time.realtimeSinceStartup;
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static class ZRoutedRpc_Constructor_PartyStats_Patch
		{
			private static void Postfix(ZRoutedRpc __instance)
			{
				__instance.Register<float, float, float, float>("BetterUI_PartyStats", (Method<float, float, float, float>)RPC_PartyStats);
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static class ZRoutedRpc_Constructor_PartyPower_Patch
		{
			private static void Postfix(ZRoutedRpc __instance)
			{
				__instance.Register<string>("BetterUI_PartyPower", (Action<long, string>)RPC_PartyPower);
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static class ZRoutedRpc_Constructor_PartyInvite_Patch
		{
			private static void Postfix(ZRoutedRpc __instance)
			{
				__instance.Register<string, string>("BetterUI_PartyInvite", (Action<long, string, string>)RPC_PartyInvite);
			}
		}

		[HarmonyPatch(typeof(Player), "GetHoverText")]
		private static class Player_GetHoverText_PartyInvite_Patch
		{
			private static void Postfix(Player __instance, ref string __result)
			{
				//IL_004a: 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_0053: 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 (!PartyEnabled.Value)
				{
					return;
				}
				Player localPlayer = Player.m_localPlayer;
				if (!((Object)(object)localPlayer == (Object)null) && !((Object)(object)__instance == (Object)(object)localPlayer))
				{
					string ownPartyId = GetOwnPartyId(localPlayer);
					bool flag = !string.IsNullOrEmpty(ownPartyId) && ownPartyId == GetOwnPartyId(__instance);
					KeyboardShortcut value = PartyInviteKey.Value;
					if ((int)((KeyboardShortcut)(ref value)).MainKey != 0)
					{
						string arg = (flag ? "Leave Party" : "Invite to Party");
						__result += $"\n[<color=yellow><b>{PartyInviteKey.Value}</b></color>] {arg}";
					}
				}
			}
		}

		private enum PartyMemberState
		{
			Normal,
			Away,
			Dead,
			Offline
		}

		private sealed class PartyDisplayEntry
		{
			public string Name;

			public Player Loaded;

			public long PeerId;

			public PartyMemberState State;
		}

		private sealed class PartyRosterEntry
		{
			public string Name;

			public long PeerId;

			public float OfflineSince = -1f;

			public float EmptyTagSince = -1f;
		}

		[HarmonyPatch(typeof(Player), "OnDeath")]
		private static class Player_OnDeath_PartyDead_Patch
		{
			private static void Postfix(Player __instance)
			{
				if (PartyEnabled.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !string.IsNullOrEmpty(savedPartyId))
				{
					sentDeadState = true;
					SendPartyDeadState(__instance, dead: true);
				}
			}
		}

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		private static class ZRoutedRpc_Constructor_PartyRoster_Patch
		{
			private static void Postfix(ZRoutedRpc __instance)
			{
				__instance.Register<string, string, bool>("BetterUI_PartyDead", (Action<long, string, string, bool>)RPC_PartyDead);
				__instance.Register<string, string>("BetterUI_PartyLeave", (Action<long, string, string>)RPC_PartyLeave);
				__instance.Register<string, string>("BetterUI_PartyHello", (Action<long, string, string>)RPC_PartyHello);
			}
		}

		private delegate Color PixelShader(float x, float y);

		[HarmonyPatch(typeof(Hud), "Awake")]
		private static class Hud_Awake_RotateHealthBar_Patch
		{
			private static void Postfix()
			{
				ApplyHealthBarRotation();
			}
		}

		[HarmonyPatch(typeof(ItemData), "GetTooltip", new Type[]
		{
			typeof(ItemData),
			typeof(int),
			typeof(bool),
			typeof(float),
			typeof(int),
			typeof(bool)
		})]
		private static class ItemData_GetTooltip_UpgradePreview_Patch
		{
			private static void Postfix(ItemData item, int qualityLevel, bool crafting, float worldLevel, ref string __result)
			{
				//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
				//IL_00af: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
				//IL_00bf: 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_00df: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
				//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
				//IL_0105: 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_0125: Unknown result type (might be due to invalid IL or missing references)
				//IL_013f: 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_015f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0165: Unknown result type (might be due to invalid IL or missing references)
				//IL_017f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0185: 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_01a5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
				//IL_01c5: Unknown result type (might be due to invalid IL or missing references)
				//IL_01df: Unknown result type (might be due to invalid IL or missing references)
				//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
				if (ShowUpgradePreview.Value && crafting && item?.m_shared != null && item.m_shared.m_maxQuality > 1 && qualityLevel > 1 && qualityLevel <= item.m_shared.m_maxQuality)
				{
					int num = qualityLevel - 1;
					upgradePreviewBuilder.Clear();
					if (item.m_shared.m_useDurability)
					{
						AppendIfIncreased(upgradePreviewBuilder, "$item_durability", item.GetMaxDurability(num), item.GetMaxDurability(qualityLevel), "0");
					}
					AppendIfIncreased(upgradePreviewBuilder, "$item_armor", item.GetArmor(num, worldLevel), item.GetArmor(qualityLevel, worldLevel), "0");
					DamageTypes damage = item.GetDamage(num, worldLevel);
					DamageTypes damage2 = item.GetDamage(qualityLevel, worldLevel);
					AppendIfIncreased(upgradePreviewBuilder, "$inventory_blunt", damage.m_blunt, damage2.m_blunt, "0");
					AppendIfIncreased(upgradePreviewBuilder, "$inventory_slash", damage.m_slash, damage2.m_slash, "0");
					AppendIfIncreased(upgradePreviewBuilder, "$inventory_pierce", damage.m_pierce, damage2.m_pierce, "0");
					AppendIfIncreased(upgradePreviewBuilder, "$inventory_chop", damage.m_chop, damage2.m_chop, "0");
					AppendIfIncreased(upgradePreviewBuilder, "$inventory_pickaxe", damage.m_pickaxe, damage2.m_pickaxe, "0");
					AppendIfIncreased(upgradePreviewBuilder, "$inventory_fire", damage.m_fire, damage2.m_fire, "0");
					AppendIfIncreased(upgradePreviewBuilder, "$inventory_frost", damage.m_frost, damage2.m_frost, "0");
					AppendIfIncreased(upgradePreviewBuilder, "$inventory_lightning", damage.m_lightning, damage2.m_lightning, "0");
					AppendIfIncreased(upgradePreviewBuilder, "$inventory_poison", damage.m_poison, damage2.m_poison, "0");
					AppendIfIncreased(upgradePreviewBuilder, "$inventory_spirit", damage.m_spirit, damage2.m_spirit, "0");
					AppendIfIncreased(upgradePreviewBuilder, "$item_blockpower", item.GetBaseBlockPower(num), item.GetBaseBlockPower(qualityLevel), "0");
					if (item.m_shared.m_timedBlockBonus > 1f)
					{
						AppendIfIncreased(upgradePreviewBuilder, "$item_deflection", item.GetDeflectionForce(num), item.GetDeflectionForce(qualityLevel), "0");
					}
					if (upgradePreviewBuilder.Length > 0)
					{
						__result = __result + "\n<color=#808080>Upgrade:</color>" + upgradePreviewBuilder;
					}
				}
			}

			private static void AppendIfIncreased(StringBuilder sb, string label, float oldValue, float newValue, string format)
			{
				if (!(newValue <= oldValue))
				{
					sb.AppendFormat("\n{0}: <color=#808080>{1}</color> {2} <color=orange>{3}</color>", Localization.instance.Localize(label), oldValue.ToString(format), "->", newValue.ToString(format));
				}
			}
		}

		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static ConsoleEvent <>9__166_0;

			public static ConsoleEvent <>9__166_1;

			public static PopupButtonCallback <>9__200_1;

			public static Func<PartyRosterEntry, string> <>9__244_0;

			public static Func<float, float, bool> <>9__263_0;

			public static EventHandler <>9__271_0;

			public static EventHandler <>9__271_1;

			public static EventHandler <>9__271_2;

			public static EventHandler <>9__271_3;

			public static EventHandler <>9__271_4;

			public static EventHandler <>9__271_5;

			public static EventHandler <>9__271_6;

			internal void <BindPartyConfig>b__166_0(ConsoleEventArgs args)
			{
				HandleInviteCommand(args);
			}

			internal void <BindPartyConfig>b__166_1(ConsoleEventArgs args)
			{
				HandlePartyLeaveCommand(args);
			}

			internal void <RPC_PartyInvite>b__200_1()
			{
				UnifiedPopup.Pop();
			}

			internal string <BuildPartyDisplayEntries>b__244_0(PartyRosterEntry e)
			{
				return e.Name;
			}

			internal bool <GetArrowSprite>b__263_0(float x, float y)
			{
				if (x >= 4f && x <= 19f && y >= 13f && y <= 19f)
				{
					return true;
				}
				if (x < 19f || x > 29f)
				{
					return false;
				}
				float num = 11f * (29f - x) / 10f;
				return Mathf.Abs(y - 16f) <= num;
			}

			internal void <BindRotateHealthBarConfig>b__271_0(object _, EventArgs _)
			{
				ApplyHealthBarRotation();
			}

			internal void <BindRotateHealthBarConfig>b__271_1(object _, EventArgs _)
			{
				ApplyHealthBarRotation();
			}

			internal void <BindRotateHealthBarConfig>b__271_2(object _, EventArgs _)
			{
				ApplyHealthBarRotation();
			}

			internal void <BindRotateHealthBarConfig>b__271_3(object _, EventArgs _)
			{
				ApplyHealthBarRotation();
			}

			internal void <BindRotateHealthBarConfig>b__271_4(object _, EventArgs _)
			{
				ApplyHealthBarRotation();
			}

			internal void <BindRotateHealthBarConfig>b__271_5(object _, EventArgs _)
			{
				ApplyHealthBarRotation();
			}

			internal void <BindRotateHealthBarConfig>b__271_6(object _, EventArgs _)
			{
				ApplyHealthBarRotation();
			}
		}

		public static ConfigEntry<bool> CharacterXPEnabled;

		private static Player xpPlayer;

		private static double xpUsed;

		private static float xpCurrent;

		public static int CharacterLevel;

		private static GuiBar xpBar;

		public static ConfigEntry<bool> ShowCharacterSelectStats;

		public static ConfigEntry<int> CharacterSelectStatsFontSize;

		public static ConfigEntry<float> CharacterSelectStatsYOffset;

		private static float csNameBaseY = float.NaN;

		public static ConfigEntry<bool> ShowCombinedItemStats;

		private static GameObject combinedStatsOverlay;

		private static UITooltip combinedStatsTooltip;

		private static readonly StringBuilder statsBuilder = new StringBuilder(256);

		public const string PluginGUID = "zenox.betterui";

		public const string PluginName = "BetterUI";

		public const string PluginVersion = "1.0.24";

		public static BetterUIPlugin Instance;

		private readonly Harmony harmony = new Harmony("zenox.betterui");

		public static ConfigEntry<bool> DurabilityColorEnabled;

		private static readonly Color[] DurabilityColors = (Color[])(object)new Color[4]
		{
			new Color(0.11765f, 0.72941f, 0.03529f, 1f),
			new Color(0.72941f, 0.72941f, 0.03529f, 1f),
			new Color(0.72941f, 0.34902f, 0.03529f, 1f),
			new Color(0.72941f, 0.03529f, 0.03529f, 1f)
		};

		private static FieldInfo hotkeyDurabilityField;

		public static ConfigEntry<int> EnemyLevelStyle;

		public static ConfigEntry<bool> ShowEnemyHpText;

		public static ConfigEntry<int> EnemyHpTextFontSize;

		public static ConfigEntry<int> BossHpTextFontSize;

		public static ConfigEntry<float> EnemyHudDistanceMultiplier;

		public static ConfigEntry<bool> ColorEnemyNameByAlertState;

		public static ConfigEntry<float> EnemyHealthBarScale;

		public static ConfigEntry<float> EnemyHealthBarHeightScale;

		public static ConfigEntry<float> EnemyNameYOffset;

		public static ConfigEntry<float> EnemyHpTextGap;

		public static ConfigEntry<float> EnemyUIAlwaysShowDistance;

		public static ConfigEntry<bool> HideEnemyBarBackground;

		private static readonly FieldInfo HudsField = AccessTools.Field(typeof(EnemyHud), "m_huds");

		private static FieldInfo hudDataNameField;

		private static FieldInfo hudDataCharacterField;

		private static FieldInfo hudDataLevel2Field;

		private static FieldInfo hudDataLevel3Field;

		private static FieldInfo hudDataHealthFastField;

		private static FieldInfo hudDataHoverTimerField;

		private static readonly Dictionary<object, TMP_Text> enemyHpLabels = new Dictionary<object, TMP_Text>();

		private static readonly Dictionary<object, float> enemyNameBaseY = new Dictionary<object, float>();

		private static bool loggedAlwaysShowOnce;

		public static ConfigEntry<bool> HoverTextExtensionsEnabled;

		public static ConfigEntry<int> ContainerHoverStyle;

		public static ConfigEntry<int> FermenterHoverStyle;

		public static ConfigEntry<int> CookingStationHoverStyle;

		public static ConfigEntry<bool> PlantGrowTimeHover;

		private static readonly MethodInfo plantGrowTimeMethod = AccessTools.Method(typeof(Plant), "GetGrowTime", (Type[])null, (Type[])null);

		private static readonly MethodInfo plantTimeSincePlantedMethod = AccessTools.Method(typeof(Plant), "TimeSincePlanted", (Type[])null, (Type[])null);

		private static FieldInfo cookingStationNviewField;

		private static MethodInfo cookingStationGetSlotMethod;

		private static MethodInfo cookingStationGetItemConversionMethod;

		private static MethodInfo cookingStationIsFireLitMethod;

		public static ConfigEntry<KeyboardShortcut> EditModeKey;

		private readonly Dictionary<string, BarOffset> barOffsets = new Dictionary<string, BarOffset>();

		private readonly Dictionary<string, RectTransform> editProxies = new Dictionary<string, RectTransform>();

		private readonly HashSet<string> wildcardCustomTargets = new HashSet<string>();

		private readonly Dictionary<string, Dictionary<RectTransform, (Vector2 pos, Vector3 scale)>> wildcardBases = new Dictionary<string, Dictionary<RectTransform, (Vector2, Vector3)>>();

		private bool editModeActive;

		private string draggingBar;

		private Vector2 dragStartMouse;

		private Vector2 dragStartOffset;

		private static HotkeyBar cachedHotkeyBar;

		public static ConfigEntry<bool> DumpHudHierarchyOnEdit;

		public static ConfigEntry<string> CustomTargetNames;

		public static ConfigEntry<bool> AutoDetectHudElements;

		public static ConfigEntry<string> AutoDetectExcludedNamesConfig;

		private const string CustomTargetPrefix = "Custom:";

		private readonly Dictionary<string, RectTransform> customTargetCache = new Dictionary<string, RectTransform>();

		private static readonly HashSet<string> AutoDetectExcludedNames = new HashSet<string> { "healthpanel", "staminapanel", "adrenalinepanel", "eitrpanel", "HotKeyBar", "StatusEffects", "MiniMap", "ZenoxCharacterXPBar", "New Game Object", "GuardianPower" };

		private static string userExcludedSource;

		private static HashSet<string> userExcludedSet = new HashSet<string>();

		private RectTransform resetButtonRt;

		private bool resetButtonWasPressed;

		private const float MinProxySize = 48f;

		public static ConfigEntry<bool> ItemLevelStarsEnabled;

		public static ConfigEntry<bool> HotbarStarsEnabled;

		public static ConfigEntry<int> InventoryStarFontSize;

		public static ConfigEntry<int> HotbarStarFontSize;

		private static readonly Color StarColor = new Color(1f, 0.85882f, 0.23137f, 1f);

		private static FieldInfo hotkeyGoField;

		private static readonly Dictionary<object, TMP_Text> hotkeyStarLabels = new Dictionary<object, TMP_Text>();

		private static bool? lastInventoryVisible;

		private const string PartyIdKey = "ZenoxPartyID";

		private const string PartyInviteRpcName = "BetterUI_PartyInvite";

		private const string PartyPowerRpcName = "BetterUI_PartyPower";

		private const string PartyStatsRpcName = "BetterUI_PartyStats";

		public static ConfigEntry<bool> PartyEnabled;

		public static ConfigEntry<bool> PartyShowHpBar;

		public static ConfigEntry<bool> PartyShowStaminaBar;

		public static ConfigEntry<bool> PartyShowGuardianPower;

		public static ConfigEntry<KeyboardShortcut> PartyInviteKey;

		private const float PartyStatsBroadcastInterval = 0.5f;

		private const float PartyStatsStaleAfter = 5f;

		private static readonly Dictionary<long, PartyStatsSnapshot> receivedPartyStats = new Dictionary<long, PartyStatsSnapshot>();

		private float lastPartyStatsBroadcastTime;

		private const float PartyPowerResendInterval = 5f;

		private const float PartyPowerStaleAfter = 15f;

		private static readonly Dictionary<long, (string power, float receivedAt)> receivedPartyPowers = new Dictionary<long, (string, float)>();

		private string lastSentPartyPower;

		private float lastPartyPowerBroadcastTime = -999f;

		private const float PowerIconSize = 18f;

		private const float StatusIconSize = 18f;

		private static readonly Color[] PartyHpColors = (Color[])(object)new Color[4]
		{
			new Color(0.11765f, 0.72941f, 0.03529f, 1f),
			new Color(0.72941f, 0.72941f, 0.03529f, 1f),
			new Color(0.72941f, 0.34902f, 0.03529f, 1f),
			new Color(0.72941f, 0.03529f, 0.03529f, 1f)
		};

		private static readonly Color PartyStaminaColor = new Color(0.85f, 0.72941f, 0.1f, 1f);

		private const float RowWidth = 190f;

		private const float RowHeight = 46f;

		private RectTransform partyFrameRt;

		private readonly List<(RectTransform row, TMP_Text nameLabel, Image hpFill, Image staminaFill)> partyRows = new List<(RectTransform, TMP_Text, Image, Image)>();

		private static readonly Dictionary<string, float> lastPartyHudLogTimeByName = new Dictionary<string, float>();

		private static Sprite whitePixelSprite;

		private const string PartyLeaveRpcName = "BetterUI_PartyLeave";

		private const string PartyDeadRpcName = "BetterUI_PartyDead";

		private const string PartyHelloRpcName = "BetterUI_PartyHello";

		private const string PartyCustomDataKey = "BetterUIPartyId";

		private const float PartyHelloInterval = 15f;

		private const float PartyOfflineRemoveAfter = 30f;

		private const float PartyOnlineRefreshInterval = 0.5f;

		private const float PartyEmptyTagRemoveAfter = 90f;

		public static ConfigEntry<KeyboardShortcut> PartyToggleKey;

		public static ConfigEntry<bool> PartyShowOfflineMembers;

		private static string savedPartyId = "";

		private static string savedPartyCharacter = "";

		private static readonly Dictionary<string, PartyRosterEntry> partyRoster = new Dictionary<string, PartyRosterEntry>();

		private static readonly Dictionary<string, bool> remoteDeadFlags = new Dictionary<string, bool>();

		private static readonly Dictionary<string, long> onlinePeerByName = new Dictionary<string, long>();

		private static float nextOnlineRefreshTime;

		private static bool sentDeadState;

		private static bool partyPanelHidden;

		private static Color partyNameDefaultColor = Color.white;

		private static bool partyNameColorCaptured;

		private static readonly Color PartyGrayText = new Color(0.62f, 0.62f, 0.62f, 1f);

		private static readonly Color PartyGrayBar = new Color(0.45f, 0.45f, 0.45f, 1f);

		private static float lastPartyHelloTime = -999f;

		private static Sprite skullSprite;

		private static Sprite arrowSprite;

		public static ConfigEntry<bool> RotateHealthBar;

		public static ConfigEntry<float> RotateHealthBarIconOffsetXVertical;

		public static ConfigEntry<float> RotateHealthBarIconOffsetYVertical;

		public static ConfigEntry<float> RotateHealthBarIconOffsetXHorizontal;

		public static ConfigEntry<float> RotateHealthBarIconOffsetYHorizontal;

		public static ConfigEntry<float> RotateHealthBarTextRotationVertical;

		public static ConfigEntry<float> RotateHealthBarTextRotationHorizontal;

		public static ConfigEntry<bool> ShowUpgradePreview;

		private const string UpgradeArrow = "->";

		private static readonly StringBuilder upgradePreviewBuilder = new StringBuilder(256);

		private void BindCharacterLevelConfig()
		{
			CharacterXPEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("CharacterLevel", "Enabled", true, "If true, shows a combined character level (sum of all skill XP) as an XP bar at the bottom of the HUD, with a level-up message.");
		}

		private static void XP_Awake(Player player)
		{
			xpPlayer = player;
			XP_UpdatePlayerXP();
			XP_UpdatePlayerLevel();
			XP_UpdateUsedXP();
		}

		private static void XP_RaiseXP()
		{
			//IL_002d: 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_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: 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)
			XP_UpdatePlayerXP();
			if ((float)((double)xpCurrent - xpUsed) >= XP_NextLevelRequirement(CharacterLevel))
			{
				XP_UpdatePlayerLevel();
				XP_UpdateUsedXP();
				Vector3 headPoint = ((Character)xpPlayer).GetHeadPoint();
				xpPlayer.m_skillLevelupEffects.Create(headPoint, ((Component)xpPlayer).transform.rotation, ((Component)xpPlayer).transform, 1.5f, -1, default(ZDOID));
				((Character)xpPlayer).Message((MessageType)2, $"<size=60><color=white>LEVEL UP</color></size>\n<size=30>You are now Lv. {CharacterLevel}</size>", 0, (Sprite)null, false);
			}
		}

		public static float XP_GetLevelPercentage()
		{
			return (float)((double)xpCurrent - xpUsed) / XP_NextLevelRequirement(CharacterLevel);
		}

		private static void XP_UpdatePlayerXP()
		{
			if ((Object)(object)xpPlayer == (Object)null)
			{
				return;
			}
			float num = 0f;
			foreach (Skill skill in ((Character)xpPlayer).GetSkills().GetSkillList())
			{
				num += (float)XP_CalculateGainedXP(skill.m_level);
				num += (float)(int)skill.m_level * skill.GetLevelPercentage();
			}
			xpCurrent = num;
		}

		private static void XP_UpdateUsedXP()
		{
			xpUsed = 12.5 * (double)(CharacterLevel * CharacterLevel) + 62.5 * (double)CharacterLevel - 75.0;
		}

		private static void XP_UpdatePlayerLevel()
		{
			CharacterLevel = Mathf.FloorToInt(-2.5f + Mathf.Sqrt(8f * xpCurrent + 1225f) / 10f);
		}

		private static float XP_NextLevelRequirement(int lvl)
		{
			return (lvl + 3) * 25;
		}

		private static int XP_CalculateGainedXP(float lvl)
		{
			return (int)lvl * ((int)lvl + 1) / 2;
		}

		private void BindCharacterSelectStatsConfig()
		{
			ShowCharacterSelectStats = ((BaseUnityPlugin)this).Config.Bind<bool>("CharacterSelectStats", "Enabled", true, "If true, shows kills/deaths/crafts/builds under the character name on the character-select screen.");
			CharacterSelectStatsFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("CharacterSelectStats", "FontSize", 22, "Font size of the kills/deaths/crafts/builds line.");
			CharacterSelectStatsYOffset = ((BaseUnityPlugin)this).Config.Bind<float>("CharacterSelectStats", "YOffset", 22f, "Moves the character name (and the stats line under it) up by this many UI pixels, to avoid the stats line hanging into the cloud-save indicator below it.");
		}

		private void BindCombinedStatsTooltipConfig()
		{
			ShowCombinedItemStats = ((BaseUnityPlugin)this).Config.Bind<bool>("CombinedStatsTooltip", "Enabled", true, "If true, hovering the armor value in the character panel shows a combined weapon/block/armor/movement stat summary instead of nothing.");
		}

		private static bool TryCreateOverlay(InventoryGui ig)
		{
			//IL_008d: 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_00a4: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: 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)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Expected O, but got Unknown
			InventoryElement val = (((Object)(object)ig.m_playerGrid == (Object)null) ? null : ((Component)ig.m_playerGrid).GetComponentInChildren<InventoryElement>(true));
			GameObject val2 = (((Object)(object)val != (Object)null && (Object)(object)val.m_tooltip != (Object)null) ? val.m_tooltip.m_tooltipPrefab : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return false;
			}
			RectTransform rectTransform = ig.m_armor.rectTransform;
			GameObject val3 = new GameObject("ZenoxArmorStatsOverlay", new Type[3]
			{
				typeof(RectTransform),
				typeof(Image),
				typeof(UITooltip)
			});
			val3.transform.SetParent(((Transform)rectTransform).parent, false);
			RectTransform component = val3.GetComponent<RectTransform>();
			component.anchorMin = rectTransform.anchorMin;
			component.anchorMax = rectTransform.anchorMax;
			component.pivot = rectTransform.pivot;
			component.anchoredPosition = rectTransform.anchoredPosition;
			component.sizeDelta = new Vector2(Mathf.Max(rectTransform.sizeDelta.x, 40f), Mathf.Max(rectTransform.sizeDelta.y, 24f));
			Image component2 = val3.GetComponent<Image>();
			((Graphic)component2).color = new Color(0f, 0f, 0f, 0f);
			((Graphic)component2).raycastTarget = true;
			UITooltip component3 = val3.GetComponent<UITooltip>();
			component3.m_tooltipPrefab = val2;
			combinedStatsOverlay = val3;
			combinedStatsTooltip = component3;
			BetterUIPlugin instance = Instance;
			if (instance != null)
			{
				((BaseUnityPlugin)instance).Logger.LogInfo((object)"[BetterUI] Combined armor/weapon stats tooltip overlay created.");
			}
			return true;
		}

		private static void AppendWeaponStats(Player player, StringBuilder sb)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Invalid comparison between Unknown and I4
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			//IL_00d3: 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_00bf: 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)
			ItemData leftItem = ((Humanoid)player).LeftItem;
			ItemData rightItem = ((Humanoid)player).RightItem;
			ItemData ammoItem = ((Humanoid)player).GetAmmoItem();
			if (leftItem != null && (int)leftItem.m_shared.m_itemType != 5)
			{
				DamageTypes damage = leftItem.GetDamage();
				if ((int)leftItem.m_shared.m_skillType == 8 && ammoItem != null)
				{
					((DamageTypes)(ref damage)).Add(ammoItem.GetDamage(), 1);
				}
				sb.Append(((DamageTypes)(ref damage)).GetTooltipString(leftItem.m_shared.m_skillType));
				sb.AppendFormat("\n\n$item_knockback: <color=orange>{0}</color>", leftItem.m_shared.m_attackForce);
				sb.AppendFormat("\n$item_backstab: <color=orange>{0}x</color>", leftItem.m_shared.m_backstabBonus);
			}
			if (rightItem != null)
			{
				DamageTypes damage2 = rightItem.GetDamage();
				if ((int)rightItem.m_shared.m_skillType == 8 && ammoItem != null)
				{
					((DamageTypes)(ref damage2)).Add(ammoItem.GetDamage(), 1);
				}
				sb.Append(((DamageTypes)(ref damage2)).GetTooltipString(rightItem.m_shared.m_skillType));
				sb.AppendFormat("\n\n$item_knockback: <color=orange>{0}</color>", rightItem.m_shared.m_attackForce);
				sb.AppendFormat("\n$item_backstab: <color=orange>{0}x</color>", rightItem.m_shared.m_backstabBonus);
			}
		}

		private static void AppendBlockStats(Player player, StringBuilder sb)
		{
			ItemData val = ((Humanoid)player).LeftItem ?? ((Humanoid)player).RightItem;
			if (val != null)
			{
				float skillFactor = ((Character)player).GetSkillFactor((SkillType)6);
				sb.AppendFormat("\n\n$item_blockpower: <color=orange>{0}</color>", Mathf.RoundToInt(val.GetBlockPower(skillFactor)));
				if (val.m_shared.m_timedBlockBonus > 1f)
				{
					sb.AppendFormat("\n$item_deflection: <color=orange>{0}</color>", Mathf.RoundToInt(val.GetDeflectionForce()));
					sb.AppendFormat("\n$item_parrybonus: <color=orange>{0}x</color>", val.m_shared.m_timedBlockBonus);
				}
			}
		}

		private void Awake()
		{
			ConfigLogDump.Schedule((BaseUnityPlugin)(object)this, ((BaseUnityPlugin)this).Logger);
			Instance = this;
			BindHudEditorConfig();
			BindEnemyLevelDisplayConfig();
			BindHoverTextExtensionsConfig();
			BindItemLevelStarsConfig();
			BindDurabilityColorConfig();
			BindCharacterLevelConfig();
			BindCharacterSelectStatsConfig();
			BindCombinedStatsTooltipConfig();
			BindUpgradePreviewTooltipConfig();
			BindPartyConfig();
			BindRotateHealthBarConfig();
			harmony.PatchAll(Assembly.GetExecutingAssembly());
			((BaseUnityPlugin)this).Logger.LogInfo((object)"BetterUI v1.0.24 loaded.");
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		private void Update()
		{
			UpdateHudEditor();
			ApplyHealthBarRotation();
			UpdatePartyHud();
			UpdatePartyInviteKey();
		}

		private void BindDurabilityColorConfig()
		{
			DurabilityColorEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("DurabilityColor", "Enabled", true, "If true, colors the item durability bar green/yellow/orange/red by remaining percentage instead of vanilla's single color.");
		}

		private static void ApplyDurabilityColor(GuiBar durabilityBar, float percentage)
		{
			//IL_004b: 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_0052: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			durabilityBar.ResetColor();
			Color color = ((percentage >= 0.75f) ? DurabilityColors[0] : ((percentage >= 0.5f) ? DurabilityColors[1] : ((percentage >= 0.25f) ? DurabilityColors[2] : DurabilityColors[3])));
			durabilityBar.SetColor(color);
		}

		private void BindEnemyLevelDisplayConfig()
		{
			EnemyLevelStyle = ((BaseUnityPlugin)this).Config.Bind<int>("EnemyLevelDisplay", "Style", 1, "How enemy level is shown. 0 = vanilla's own star icons only, 1 = text star prefix (same style as item quality stars) instead of vanilla's icons, 2 = both.");
			ShowEnemyHpText = ((BaseUnityPlugin)this).Config.Bind<bool>("EnemyLevelDisplay", "ShowHpText", true, "If true, shows a 'current/max' HP number under enemy nameplates.");
			EnemyHpTextFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("EnemyLevelDisplay", "HpTextFontSize", 11, "Font size of the HP number on regular enemy health bars.");
			BossHpTextFontSize = ((BaseUnityPlugin)this).Config.Bind<int>("EnemyLevelDisplay", "BossHpTextFontSize", 18, "Font size of the HP number on the (larger) boss health bar.");
			EnemyHudDistanceMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("EnemyLevelDisplay", "DistanceMultiplier", 1f, "Multiplies how far away enemy HUDs (health bar/nameplate) become visible. 1 = vanilla default.");
			ColorEnemyNameByAlertState = ((BaseUnityPlugin)this).Config.Bind<bool>("EnemyLevelDisplay", "ColorNameByAlertState", true, "If true, tints the enemy name white/yellow/red depending on whether it's aware of or alerted to the player.");
			EnemyHealthBarScale = ((BaseUnityPlugin)this).Config.Bind<float>("EnemyLevelDisplay", "HealthBarScale", 1.1f, "Scale multiplier for the enemy health bar (width and height). 1 = vanilla size.");
			EnemyHealthBarHeightScale = ((BaseUnityPlugin)this).Config.Bind<float>("EnemyLevelDisplay", "HealthBarHeightScale", 1.5f, "Extra scale multiplier applied to the bar's HEIGHT only, on top of HealthBarScale - makes the bar taller/thicker without also widening it further.");
			EnemyNameYOffset = ((BaseUnityPlugin)this).Config.Bind<float>("EnemyLevelDisplay", "NameYOffset", 2f, "Moves the enemy name up by this many UI pixels, to make room for the bigger bar/HP text below it.");
			EnemyHpTextGap = ((BaseUnityPlugin)this).Config.Bind<float>("EnemyLevelDisplay", "HpTextGap", 11f, "Vertical gap between the enemy name and the HP text below it.");
			HideEnemyBarBackground = ((BaseUnityPlugin)this).Config.Bind<bool>("EnemyLevelDisplay", "HideBarBackground", true, "If true, hides the dark background panel behind the enemy health bar.");
			EnemyUIAlwaysShowDistance = ((BaseUnityPlugin)this).Config.Bind<float>("EnemyLevelDisplay", "AlwaysShowDistance", 30f, "Enemy HUD (bar/nameplate) is always shown for any enemy within this distance, instead of only appearing while the crosshair is aimed at it. 0 = disabled (vanilla hover-only behavior).");
		}

		private static void SetActiveIfPresent(RectTransform rt, bool active)
		{
			if ((Object)(object)rt != (Object)null)
			{
				((Component)rt).gameObject.SetActive(active);
			}
		}

		private static TMP_Text GetOrCreateHpLabel(object hudData, TextMeshProUGUI nameTemplate)
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			if (enemyHpLabels.TryGetValue(hudData, out var value) && (Object)(object)value != (Object)null)
			{
				((Component)value).gameObject.SetActive(true);
				return value;
			}
			TMP_Text val = (TMP_Text)(object)Object.Instantiate<TextMeshProUGUI>(nameTemplate, ((TMP_Text)nameTemplate).transform.parent);
			((Object)val).name = "ZenoxEnemyHpText";
			for (int num = val.transform.childCount - 1; num >= 0; num--)
			{
				GameObject gameObject = ((Component)val.transform.GetChild(num)).gameObject;
				gameObject.SetActive(false);
				Object.Destroy((Object)(object)gameObject);
			}
			((Component)val).gameObject.SetActive(true);
			((Graphic)val).color = Color.white;
			val.alignment = (TextAlignmentOptions)514;
			val.rectTransform.pivot = new Vector2(0.5f, 0.5f);
			enemyHpLabels[hudData] = val;
			return val;
		}

		private void BindHoverTextExtensionsConfig()
		{
			HoverTextExtensionsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("HoverText", "Enabled", true, "If true, adds extra info lines to container/fermenter/cooking station hover text.");
			ContainerHoverStyle = ((BaseUnityPlugin)this).Config.Bind<int>("HoverText", "ContainerStyle", 3, "How chest fullness is shown. 0 = off, 1 = % used, 2 = items/max, 3 = free slots.");
			FermenterHoverStyle = ((BaseUnityPlugin)this).Config.Bind<int>("HoverText", "FermenterStyle", 2, "How fermenter progress is shown while brewing. 0 = off, 1 = % done, 2 = mm:ss remaining.");
			PlantGrowTimeHover = ((BaseUnityPlugin)this).Config.Bind<bool>("HoverText", "PlantGrowTime", true, "If true, planted crops/saplings show the time left until fully grown.");
			CookingStationHoverStyle = ((BaseUnityPlugin)this).Config.Bind<int>("HoverText", "CookingStationStyle", 2, "How cooking progress is shown per slot. 0 = off, 1 = % done, 2 = mm:ss remaining.");
		}

		private static string FormatDuration(double seconds)
		{
			if (seconds < 0.0)
			{
				seconds = 0.0;
			}
			TimeSpan timeSpan = TimeSpan.FromSeconds(seconds);
			if (timeSpan.TotalHours >= 1.0)
			{
				return $"{(int)timeSpan.TotalHours}h {timeSpan.Minutes}m";
			}
			if (timeSpan.TotalMinutes >= 1.0)
			{
				return $"{timeSpan.Minutes}m {timeSpan.Seconds}s";
			}
			return $"{timeSpan.Seconds}s";
		}

		private void BindHudEditorConfig()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			EditModeKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("HudEditor", "EditModeKey", new KeyboardShortcut((KeyCode)288, Array.Empty<KeyCode>()), "Toggle HUD edit mode: while active, drag a bar's proxy box with the left mouse button to move it, scroll while hovering it to resize it.");
			DumpHudHierarchyOnEdit = ((BaseUnityPlugin)this).Config.Bind<bool>("HudEditor", "DumpHudHierarchyOnEdit", false, "If true, logs the full HUD canvas hierarchy (every active UI element's name and path) once each time edit mode is turned on - use this to find the exact name of an element (vanilla, ours, or from another mod) to enter in CustomTargetNames.");
			CustomTargetNames = ((BaseUnityPlugin)this).Config.Bind<string>("HudEditor", "CustomTargetNames", "", "Comma-separated GameObject names to make movable/scalable in edit mode alongside the built-in bars, e.g. 'karma_icon,SomeOtherModPanel'. Only needed for elements AutoDetectHudElements can't reach (nested deeper than a direct hudroot child) - use DumpHudHierarchyOnEdit to find the exact name of the element you want.\nTwo elements with the SAME name (e.g. the minimap's small-view and large-map player markers both being named 'player_marker') can't be told apart by name alone - use a hierarchy PATH SUFFIX instead (copy it from the DumpHudHierarchyOnEdit log), e.g. 'large/map/player_marker' matches only the one whose full path ends that way.\nEach entry can optionally set its own starting offset/scale with 'name:offsetX:offsetY:scale' (e.g. 'karma_icon:10:-5:1.2') - only takes effect the FIRST time that entry is created (same as every other default here), not on an entry that's already been saved to this config file.\nA leading '*' (e.g. '*BoatTrackingName') applies the SAME offset/scale to EVERY currently-existing instance of that name at once, instead of only the first one found - for elements that exist once per dynamic object (one per boat, one per ship, etc.) rather than once total. Edit-mode drag/scroll isn't available for wildcard entries, only the config's OffsetX/OffsetY/Scale values directly.");
			AutoDetectHudElements = ((BaseUnityPlugin)this).Config.Bind<bool>("HudEditor", "AutoDetectHudElements", true, "If true, automatically finds and makes movable any top-level HUD panel that isn't already covered by a built-in bar or CustomTargetNames - including ones added by other mods - with no need to enter names manually. Re-checked continuously while edit mode is on, so panels that only appear later (e.g. after first use) get picked up live.");
			AutoDetectExcludedNamesConfig = ((BaseUnityPlugin)this).Config.Bind<string>("HudEditor", "AutoDetectExcludedNames", "", "Comma-separated GameObject names that AutoDetectHudElements must never register as movable (a blacklist, e.g. 'SomeOverlay,AnotherPanel'). The full-screen damage flash and any element stretched over the whole screen are already excluded automatically.");
			BindBarOffset("HealthBar");
			BindBarOffset("StaminaBar");
			BindBarOffset("FoodBar");
			BindBarOffset("EitrBar");
			BindBarOffset("AdrenalineBar");
			BindBarOffset("GuardianPower");
			BindBarOffset("StatusEffects");
			BindBarOffset("Hotbar");
			BindBarOffset("Minimap");
			BindBarOffset("XPBar");
			string[] array = CustomTargetNames.Value.Split(',');
			for (int i = 0; i < array.Length; i++)
			{
				string text = array[i].Trim();
				if (text.Length == 0)
				{
					continue;
				}
				string[] array2 = text.Split(':');
				string text2 = array2[0].Trim();
				if (text2.Length == 0)
				{
					continue;
				}
				bool flag = text2.StartsWith("*");
				if (flag)
				{
					text2 = text2.Substring(1).Trim();
				}
				if (text2.Length != 0)
				{
					float result;
					float defaultOffsetX = ((array2.Length > 1 && float.TryParse(array2[1], NumberStyles.Float, CultureInfo.InvariantCulture, out result)) ? result : 0f);
					float result2;
					float defaultOffsetY = ((array2.Length > 2 && float.TryParse(array2[2], NumberStyles.Float, CultureInfo.InvariantCulture, out result2)) ? result2 : 0f);
					float result3;
					float defaultScale = ((array2.Length > 3 && float.TryParse(array2[3], NumberStyles.Float, CultureInfo.InvariantCulture, out result3)) ? result3 : 1f);
					string text3 = "Custom:" + text2;
					BindBarOffset(text3, defaultOffsetX, defaultOffsetY, defaultScale);
					if (flag)
					{
						wildcardCustomTargets.Add(text3);
					}
				}
			}
		}

		private void BindBarOffset(string barName, float defaultOffsetX = 0f, float defaultOffsetY = 0f, float defaultScale = 1f)
		{
			BarOffset offset = new BarOffset
			{
				Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("HudEditor", barName + ".Enabled", true, "If false, BetterUI never touches the " + barName + "'s position/scale at all (not even to apply a saved offset) - use this to let another mod control this element instead."),
				OffsetX = ((BaseUnityPlugin)this).Config.Bind<float>("HudEditor", barName + ".OffsetX", defaultOffsetX, "Horizontal offset for the " + barName + ", in UI pixels."),
				OffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("HudEditor", barName + ".OffsetY", defaultOffsetY, "Vertical offset for the " + barName + ", in UI pixels."),
				Scale = ((BaseUnityPlugin)this).Config.Bind<float>("HudEditor", barName + ".Scale", defaultScale, "Scale multiplier for the " + barName + ". 1 = vanilla size.")
			};
			barOffsets[barName] = offset;
			offset.Enabled.SettingChanged += delegate
			{
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0069: Unknown result type (might be due to invalid IL or missing references)
				if (!offset.Enabled.Value && offset.Captured)
				{
					RectTransform[] barRoots = GetBarRoots(barName);
					for (int i = 0; i < barRoots.Length && i < offset.BaseAnchoredPositions.Length; i++)
					{
						if (!((Object)(object)barRoots[i] == (Object)null))
						{
							barRoots[i].anchoredPosition = offset.BaseAnchoredPositions[i];
							((Transform)barRoots[i]).localScale = offset.BaseScales[i];
						}
					}
					offset.Captured = false;
					if (editProxies.TryGetValue(barName, out var value) && (Object)(object)value != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)value).gameObject);
						editProxies.Remove(barName);
					}
				}
			};
		}

		private RectTransform GetBarRoot(string barName)
		{
			if (barName.StartsWith("Custom:"))
			{
				return ResolveCustomTarget(barName.Substring("Custom:".Length));
			}
			Hud instance = Hud.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return null;
			}
			switch (barName)
			{
			case "HealthBar":
				return instance.m_healthBarRoot;
			case "StaminaBar":
				return instance.m_staminaBar2Root;
			case "FoodBar":
				return ResolveCustomTarget("food0");
			case "EitrBar":
				return instance.m_eitrBarRoot;
			case "AdrenalineBar":
				return instance.m_adrenalineBarRoot;
			case "GuardianPower":
				return instance.m_gpRoot;
			case "StatusEffects":
				return instance.m_statusEffectListRoot;
			case "Hotbar":
				if (!((Object)(object)cachedHotkeyBar != (Object)null))
				{
					return null;
				}
				return ((Component)cachedHotkeyBar).GetComponent<RectTransform>();
			case "Minimap":
				if (!((Object)(object)Minimap.instance != (Object)null) || !((Object)(object)Minimap.instance.m_smallRoot != (Object)null))
				{
					return null;
				}
				return Minimap.instance.m_smallRoot.GetComponent<RectTransform>();
			case "XPBar":
			{
				if (!((Object)(object)xpBar != (Object)null))
				{
					return null;
				}
				Transform transform = ((Component)xpBar).transform;
				return (RectTransform)(object)((transform is RectTransform) ? transform : null);
			}
			case "PartyFrame":
				return partyFrameRt;
			default:
				return null;
			}
		}

		private void AutoDetectNewHudElements()
		{
			if (!AutoDetectHudElements.Value)
			{
				return;
			}
			Hud instance = Hud.instance;
			Canvas val = (((Object)(object)instance != (Object)null) ? ((Component)instance).GetComponentInParent<Canvas>() : null);
			Transform val2 = (((Object)(object)val != (Object)null) ? ((Component)val).transform.Find("hudroot") : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			for (int i = 0; i < val2.childCount; i++)
			{
				Transform child = val2.GetChild(i);
				string name = ((Object)child).name;
				if (string.IsNullOrEmpty(name) || AutoDetectExcludedNames.Contains(name) || IsUserExcluded(name))
				{
					continue;
				}
				string text = "Custom:" + name;
				if (!barOffsets.ContainsKey(text))
				{
					RectTransform val3 = (RectTransform)(object)((child is RectTransform) ? child : null);
					if (val3 != null && !IsAutoDetectBlacklisted(instance, val3))
					{
						BindBarOffset(text);
						((BaseUnityPlugin)this).Logger.LogInfo((object)("[BetterUI HudEditor] Auto-detected new HUD element: '" + name + "' - now movable in edit mode."));
					}
				}
			}
		}

		private static bool IsUserExcluded(string name)
		{
			string value = AutoDetectExcludedNamesConfig.Value;
			if (value != userExcludedSource)
			{
				userExcludedSource = value;
				userExcludedSet = new HashSet<string>();
				string[] array = value.Split(',');
				for (int i = 0; i < array.Length; i++)
				{
					string text = array[i].Trim();
					if (text.Length > 0)
					{
						userExcludedSet.Add(text);
					}
				}
			}
			return userExcludedSet.Contains(name);
		}

		private static bool IsAutoDetectBlacklisted(Hud hud, RectTransform child)
		{
			//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_004d: 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_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)hud != (Object)null && (Object)(object)hud.m_damageScreen != (Object)null)
			{
				Transform transform = ((Component)hud.m_damageScreen).transform;
				if ((Object)(object)transform == (Object)(object)child || transform.IsChildOf((Transform)(object)child))
				{
					return true;
				}
			}
			Vector2 val = child.anchorMin;
			if (((Vector2)(ref val)).sqrMagnitude < 0.0001f)
			{
				val = child.anchorMax - Vector2.one;
				return ((Vector2)(ref val)).sqrMagnitude < 0.0001f;
			}
			return false;
		}

		private RectTransform ResolveCustomTarget(string name)
		{
			if (customTargetCache.TryGetValue(name, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Hud instance = Hud.instance;
			Canvas val = (((Object)(object)instance != (Object)null) ? ((Component)instance).GetComponentInParent<Canvas>() : null);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			bool flag = name.IndexOf('/') >= 0;
			string text = name.Replace('\\', '/').Trim('/');
			string value2 = "/" + text;
			string text2 = (flag ? text.Substring(text.LastIndexOf('/') + 1) : name);
			RectTransform val2 = null;
			RectTransform[] componentsInChildren = ((Component)val).GetComponentsInChildren<RectTransform>(true);
			foreach (RectTransform val3 in componentsInChildren)
			{
				if (!(((Object)val3).name != text2) && (!flag || GetHierarchyPath((Transform)(object)val3).EndsWith(value2, StringComparison.Ordinal)))
				{
					val2 = val3;
					break;
				}
			}
			if ((Object)(object)val2 != (Object)null)
			{
				customTargetCache[name] = val2;
			}
			return val2;
		}

		private static string GetHierarchyPath(Transform t)
		{
			string text = ((Object)t).name;
			Transform parent = t.parent;
			while ((Object)(object)parent != (Object)null)
			{
				text = ((Object)parent).name + "/" + text;
				parent = parent.parent;
			}
			return text;
		}

		private List<RectTransform> ResolveCustomTargetsAll(string name)
		{
			List<RectTransform> list = new List<RectTransform>();
			Hud instance = Hud.instance;
			Canvas val = (((Object)(object)instance != (Object)null) ? ((Component)instance).GetComponentInParent<Canvas>() : null);
			if ((Object)(object)val == (Object)null)
			{
				return list;
			}
			bool flag = name.IndexOf('/') >= 0;
			string text = name.Replace('\\', '/').Trim('/');
			string value = "/" + text;
			string text2 = (flag ? text.Substring(text.LastIndexOf('/') + 1) : name);
			RectTransform[] componentsInChildren = ((Component)val).GetComponentsInChildren<RectTransform>(true);
			foreach (RectTransform val2 in componentsInChildren)
			{
				if (!(((Object)val2).name != text2) && (!flag || GetHierarchyPath((Transform)(object)val2).EndsWith(value, StringComparison.Ordinal)))
				{
					list.Add(val2);
				}
			}
			return list;
		}

		private void ApplyWildcardCustomTargets()
		{
			//IL_0184: Unknown result type (might be due to invalid IL or missing references)
			//IL_0189: Unknown result type (might be due to invalid IL or missing references)
			//IL_018b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0162: Unknown result type (might be due to invalid IL or missing references)
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			if (wildcardCustomTargets.Count == 0)
			{
				return;
			}
			Vector2 val = default(Vector2);
			foreach (string wildcardCustomTarget in wildcardCustomTargets)
			{
				if (!barOffsets.TryGetValue(wildcardCustomTarget, out var value) || !value.Enabled.Value)
				{
					continue;
				}
				string name = wildcardCustomTarget.Substring("Custom:".Length);
				List<RectTransform> list = ResolveCustomTargetsAll(name);
				if (!wildcardBases.TryGetValue(wildcardCustomTarget, out Dictionary<RectTransform, (Vector2, Vector3)> value2))
				{
					value2 = new Dictionary<RectTransform, (Vector2, Vector3)>();
					wildcardBases[wildcardCustomTarget] = value2;
				}
				List<RectTransform> list2 = null;
				foreach (RectTransform key in value2.Keys)
				{
					if ((Object)(object)key == (Object)null)
					{
						(list2 ?? (list2 = new List<RectTransform>())).Add(key);
					}
				}
				if (list2 != null)
				{
					foreach (RectTransform item in list2)
					{
						value2.Remove(item);
					}
				}
				((Vector2)(ref val))..ctor(value.OffsetX.Value, value.OffsetY.Value);
				foreach (RectTransform item2 in list)
				{
					if (!((Object)(object)item2 == (Object)null))
					{
						if (!value2.TryGetValue(item2, out var value3))
						{
							value3 = (value2[item2] = (item2.anchoredPosition, ((Transform)item2).localScale));
						}
						item2.anchoredPosition = value3.Item1 + val;
						((Transform)item2).localScale = value3.Item2 * value.Scale.Value;
					}
				}
			}
		}

		private RectTransform[] GetBarRoots(string barName)
		{
			if (barName == "FoodBar")
			{
				RectTransform val = ResolveCustomTarget("food0");
				RectTransform val2 = ResolveCustomTarget("food1");
				RectTransform val3 = ResolveCustomTarget("food2");
				RectTransform val4 = ResolveCustomTarget("foodicon (1)");
				List<RectTransform> list = new List<RectTransform>(4);
				if ((Object)(object)val != (Object)null)
				{
					list.Add(val);
				}
				if ((Object)(object)val2 != (Object)null)
				{
					list.Add(val2);
				}
				if ((Object)(object)val3 != (Object)null)
				{
					list.Add(val3);
				}
				if ((Object)(object)val4 != (Object)null)
				{
					list.Add(val4);
				}
				return list.ToArray();
			}
			if (barName == "HealthBar")
			{
				RectTransform barRoot = GetBarRoot("HealthBar");
				if ((Object)(object)barRoot == (Object)null)
				{
					return Array.Empty<RectTransform>();
				}
				RectTransform val5 = ResolveCustomTarget("healthicon");
				if ((Object)(object)val5 != (Object)null)
				{
					return (RectTransform[])(object)new RectTransform[2] { barRoot, val5 };
				}
				return (RectTransform[])(object)new RectTransform[1] { barRoot };
			}
			RectTransform barRoot2 = GetBarRoot(barName);
			if (!((Object)(object)barRoot2 != (Object)null))
			{
				return Array.Empty<RectTransform>();
			}
			return (RectTransform[])(object)new RectTransform[1] { barRoot2 };
		}

		private RectTransform GetOrCreateProxy(string barName)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			if (editProxies.TryGetValue(barName, out var value) && (Object)(object)value != (Object)null)
			{
				return value;
			}
			Hud instance = Hud.instance;
			Canvas val = (((Object)(object)instance != (Object)null) ? ((Component)instance).GetComponentInParent<Canvas>() : null);
			if ((Object)(object)val == (Object)null)
			{
				return null;
			}
			GameObject val2 = new GameObject("BetterUIHudEditProxy_" + barName, new Type[2]
			{
				typeof(RectTransform),
				typeof(Image)
			});
			val2.transform.SetParent(((Component)val).transform, false);
			RectTransform component = val2.GetComponent<RectTransform>();
			component.sizeDelta = new Vector2(130f, 30f);
			((Graphic)val2.GetComponent<Image>()).color = new Color(0.1f, 0.55f, 1f, 0f);
			editProxies[barName] = component;
			return component;
		}

		private void DestroyAllProxies()
		{
			foreach (KeyValuePair<string, RectTransform> editProxy in editProxies)
			{
				if ((Object)(object)editProxy.Value != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)editProxy.Value).gameObject);
				}
			}
			editProxies.Clear();
		}

		private void CreateResetButton()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Expected O, but got Unknown
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: 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_015a: 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_0175: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_018a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)resetButtonRt != (Object)null)
			{
				return;
			}
			Hud instance = Hud.instance;
			Canvas val = (((Object)(object)instance != (Object)null) ? ((Component)instance).GetComponentInParent<Canvas>() : null);
			if (!((Object)(object)val == (Object)null))
			{
				GameObject val2 = new GameObject("BetterUIHudEditResetButton", new Type[2]
				{
					typeof(RectTransform),
					typeof(Image)
				});
				val2.transform.SetParent(((Component)val).transform, false);
				RectTransform component = val2.GetComponent<RectTransform>();
				component.sizeDelta = new Vector2(170f, 44f);
				component.anchorMin = new Vector2(1f, 0.5f);
				component.anchorMax = new Vector2(1f, 0.5f);
				component.pivot = new Vector2(1f, 0.5f);
				component.anchoredPosition = new Vector2(-20f, 0f);
				((Graphic)val2.GetComponent<Image>()).color = new Color(0.75f, 0.15f, 0.15f, 0.9f);
				if ((Object)(object)instance.m_foodText != (Object)null)
				{
					TMP_Text obj = Object.Instantiate<TMP_Text>(instance.m_foodText, val2.transform);
					((Component)obj).gameObject.SetActive(true);
					obj.text = "Reset HUD";
					obj.alignment = (TextAlignmentOptions)514;
					obj.enableAutoSizing = false;
					obj.fontSize = 20f;
					((Graphic)obj).color = Color.white;
					RectTransform rectTransform = obj.rectTransform;
					rectTransform.anchorMin = Vector2.zero;
					rectTransform.anchorMax = Vector2.one;
					rectTransform.offsetMin = Vector2.zero;
					rectTransform.offsetMax = Vector2.zero;
				}
				resetButtonRt = component;
				resetButtonWasPressed = false;
			}
		}

		private void HandleResetButtonInput()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (!((Object)(object)resetButtonRt == (Object)null))
			{
				bool flag = RectTransformUtility.RectangleContainsScreenPoint(resetButtonRt, Vector2.op_Implicit(Input.mousePosition)) && Input.GetMouseButtonDown(0);
				if (flag && !resetButtonWasPressed)
				{
					ResetAllBarOffsets();
				}
				resetButtonWasPressed = flag;
			}
		}

		private void ResetAllBarOffsets()
		{
			foreach (BarOffset value in barOffsets.Values)
			{
				value.OffsetX.Value = 0f;
				value.OffsetY.Value = 0f;
				value.Scale.Value = 1f;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[BetterUI HudEditor] Reset all HUD element positions/scales to default.");
		}

		private void UpdateHudEditor()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: 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_0142: Unknown result type (might be due to invalid IL or missing references)
			//IL_0147: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: 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)
			KeyboardShortcut value = EditModeKey.Value;
			if (((KeyboardShortcut)(ref value)).IsDown())
			{
				editModeActive = !editModeActive;
				((BaseUnityPlugin)this).Logger.LogInfo((object)(editModeActive ? "BetterUI: HUD edit mode ON (drag a bar's blue proxy box to move it, scroll while hovering it to resize)." : "BetterUI: HUD edit mode OFF."));
				if (editModeActive)
				{
					LogBarRootDiagnosticsOnce();
					CreateResetButton();
				}
				else
				{
					DestroyAllProxies();
					if ((Object)(object)resetButtonRt != (Object)null)
					{
						Object.Destroy((Object)(object)((Component)resetButtonRt).gameObject);
						resetButtonRt = null;
					}
					draggingBar = null;
					Hud_Update_ForceBarsVisible_HudEditor_Patch.RestoreForcedActiveStates();
				}
			}
			AutoDetectNewHudElements();
			if (editModeActive)
			{
				HandleResetButtonInput();
			}
			ApplyWildcardCustomTargets();
			Vector2 val = default(Vector2);
			foreach (KeyValuePair<string, BarOffset> barOffset in barOffsets)
			{
				string key = barOffset.Key;
				if (wildcardCustomTargets.Contains(key))
				{
					continue;
				}
				BarOffset value2 = barOffset.Value;
				if (!value2.Enabled.Value)
				{
					continue;
				}
				RectTransform[] barRoots = GetBarRoots(key);
				if (barRoots.Length == 0)
				{
					continue;
				}
				if (!value2.Captured)
				{
					value2.BaseAnchoredPositions = (Vector2[])(object)new Vector2[barRoots.Length];
					value2.BaseScales = (Vector3[])(object)new Vector3[barRoots.Length];
					for (int i = 0; i < barRoots.Length; i++)
					{
						value2.BaseAnchoredPositions[i] = barRoots[i].anchoredPosition;
						value2.BaseScales[i] = ((Transform)barRoots[i]).localScale;
					}
					value2.Captured = true;
				}
				((Vector2)(ref val))..ctor(value2.OffsetX.Value, value2.OffsetY.Value);
				for (int j = 0; j < barRoots.Length; j++)
				{
					barRoots[j].anchoredPosition = value2.BaseAnchoredPositions[j] + val;
					((Transform)barRoots[j]).localScale = value2.BaseScales[j] * value2.Scale.Value;
				}
				if (editModeActive)
				{
					RectTransform orCreateProxy = GetOrCreateProxy(key);
					if ((Object)(object)orCreateProxy != (Object)null)
					{
						SyncProxyToTargets(orCreateProxy, barRoots);
						HandleBarEditInput(key, value2, orCreateProxy);
					}
				}
			}
		}

		private static void SyncProxyToTargets(RectTransform proxy, RectTransform[] targets)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: 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_00a1: 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_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00de: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_0067: 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_006a: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: 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)
			Vector3 val = default(Vector3);
			((Vector3)(ref val))..ctor(float.MaxValue, float.MaxValue, 0f);
			Vector3 val2 = default(Vector3);
			((Vector3)(ref val2))..ctor(float.MinValue, float.MinValue, 0f);
			Vector3[] array = (Vector3[])(object)new Vector3[4];
			foreach (RectTransform val3 in targets)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					val3.GetWorldCorners(array);
					Vector3[] array2 = array;
					foreach (Vector3 val4 in array2)
					{
						val = Vector3.Min(val, val4);
						val2 = Vector3.Max(val2, val4);
					}
				}
			}
			Vector3 position = (val + val2) * 0.5f;
			float num = Mathf.Max(val2.x - val.x, 48f);
			float num2 = Mathf.Max(val2.y - val.y, 48f);
			proxy.sizeDelta = new Vector2(num, num2);
			((Transform)proxy).position = position;
		}

		private void LogBarRootDiagnosticsOnce()
		{
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			foreach (string key in barOffsets.Keys)
			{
				RectTransform barRoot = GetBarRoot(key);
				if ((Object)(object)barRoot == (Object)null)
				{
					((BaseUnityPlugin)this).Logger.LogInfo((object)("[BetterUI HudEditor] GetBarRoot('" + key + "') = null (no proxy possible)."));
					continue;
				}
				Vector3[] array = (Vector3[])(object)new Vector3[4];
				barRoot.GetWorldCorners(array);
				((BaseUnityPlugin)this).Logger.LogInfo((object)$"[BetterUI HudEditor] GetBarRoot('{key}') = '{((Object)barRoot).name}', worldCorners=[{array[0]},{array[2]}], active={((Component)barRoot).gameObject.activeInHierarchy}");
			}
			Hud instance = Hud.instance;
			if ((Object)(object)instance != (Object)null)
			{
				bool flag = (Object)(object)instance.m_foodIcon != (Object)null;
				((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("[BetterUI HudEditor] hud.m_foodIcon = {0}, active={1}", flag ? ((Object)instance.m_foodIcon).name : "null", flag && ((Component)instance.m_foodIcon).gameObject.activeInHierarchy));
			}
			if (DumpHudHierarchyOnEdit.Value)
			{
				DumpHudHierarchy();
			}
		}

		private void DumpHudHierarchy()
		{
			Hud instance = Hud.instance;
			Canvas val = (((Object)(object)instance != (Object)null) ? ((Component)instance).GetComponentInParent<Canvas>() : null);
			if ((Object)(object)val == (Object)null)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)"[BetterUI HudEditor] DumpHudHierarchy: no HUD canvas found.");
				return;
			}
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[BetterUI HudEditor] --- HUD hierarchy dump start ---");
			DumpHudHierarchyRecursive(((Component)val).transform, "");
			((BaseUnityPlugin)this).Logger.LogInfo((object)"[BetterUI HudEditor] --- HUD hierarchy dump end ---");
		}

		private void DumpHudHierarchyRecursive(Transform t, string path)
		{
			string text = ((path.Length == 0) ? ((Object)t).name : (path + "/" + ((Object)t).name));
			if (((Component)t).gameObject.activeInHierarchy)
			{
				((BaseUnityPlugin)this).Logger.LogInfo((object)("[BetterUI HudEditor] " + text));
			}
			for (int i = 0; i < t.childCount; i++)
			{
				DumpHudHierarchyRecursive(t.GetChild(i), text);
			}
		}

		private void HandleBarEditInput(string barName, BarOffset offset, RectTransform proxyRt)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: 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_007b: 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_009c: 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_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: 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_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fc: Unknown result type (might b