Decompiled source of QualityLifeMod v0.2.7

plugins/QualitylifeMod.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("QualitylifeMod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("QualitylifeMod")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("d6901057-1b15-472d-adff-f1c757057d38")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace QualityLifeMod;

[Serializable]
public class QualityLifeContainerSaveData
{
	public string containerId;

	public string withdrawLabel;

	public string depositLabel;

	public string productionCategory;

	public Vector3 containerPosition;

	public bool hasContainerPosition;
}
[Serializable]
public class QualityLifeZoneSaveData
{
	public string workbenchId;

	public string worldId;

	public string craftingStationName;

	public List<string> craftingStationIds = new List<string>();

	public Vector3 workbenchPosition;

	public List<Vector3> points = new List<Vector3>();

	public List<Vector3> basePoints = new List<Vector3>();

	public List<Vector3> originalBasePoints = new List<Vector3>();

	public float rotationDegrees;

	public float trimSideA;

	public float trimSideB;

	public float trimSideC;

	public float trimSideD;

	public List<string> priorityContainerIds = new List<string>();

	public List<string> depositContainerIds = new List<string>();

	public List<string> containerOrderIds = new List<string>();

	public List<QualityLifeContainerSaveData> containerSettings = new List<QualityLifeContainerSaveData>();

	public List<string> productionCategories = new List<string>();
}
[Serializable]
public class QualityLifeZoneFile
{
	public int dataVersion = 6;

	public string worldId;

	public string playerId;

	public List<QualityLifeZoneSaveData> zones = new List<QualityLifeZoneSaveData>();

	public string selectedBuilderZoneWorkbenchId;
}
[BepInPlugin("Custom.qualitylife.mod", "Quality Life Mod", "0.2.1")]
public class Plugin : BaseUnityPlugin
{
	[Serializable]
	public class SavedZone
	{
		public string workbenchId;

		public string worldId;

		public string craftingStationName;

		public List<string> craftingStationIds = new List<string>();

		public Vector3 workbenchPosition;

		public List<Vector3> points = new List<Vector3>();

		public List<Vector3> basePoints = new List<Vector3>();

		public List<Vector3> originalBasePoints = new List<Vector3>();

		public float rotationDegrees;

		public float trimSideA;

		public float trimSideB;

		public float trimSideC;

		public float trimSideD;

		public List<string> priorityContainerIds = new List<string>();

		public List<string> depositContainerIds = new List<string>();

		public List<string> containerOrderIds = new List<string>();

		public List<QualityLifeContainerSaveData> containerSettings = new List<QualityLifeContainerSaveData>();

		public List<string> productionCategories = new List<string>();
	}

	private class HouseResourceData
	{
		public string itemName;

		public int amount;

		public Sprite icon;
	}

	private sealed class ContainerMatchCandidate
	{
		public QualityLifeContainerSaveData saved;

		public Container live;

		public float distance;
	}

	public static Plugin Instance;

	internal static Harmony Harmony;

	internal static bool Initialized;

	private readonly Dictionary<string, Coroutine> activeProductionAutomations = new Dictionary<string, Coroutine>();

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

	private const float ProductionAutomationInterval = 0.5f;

	private const float CookingAutomationInterval = 0.8f;

	internal const string ModName = "Quality Life Mod";

	internal const string Version = "0.2.1";

	private ConfigEntry<KeyboardShortcut> configMenuHotkey;

	private ConfigEntry<KeyboardShortcut> chestManagementMenuHotkey;

	private ConfigEntry<KeyboardShortcut> loadHouseZonesHotkey;

	private ConfigEntry<KeyboardShortcut> createHouseZoneHotkey;

	private ConfigEntry<KeyboardShortcut> builderZoneHotkey;

	private ConfigEntry<KeyboardShortcut> deleteSelectedZoneHotkey;

	private ConfigEntry<KeyboardShortcut> deleteAllZonesHotkey;

	private ConfigEntry<KeyboardShortcut> priorityInputChestHotkey;

	private ConfigEntry<KeyboardShortcut> priorityInputChestRemoveHotkey;

	private ConfigEntry<KeyboardShortcut> priorityDepositChestHotkey;

	private ConfigEntry<KeyboardShortcut> priorityDepositChestRemoveHotkey;

	private ConfigEntry<float> chestRoleUIPositionX;

	private ConfigEntry<float> chestRoleUIPositionY;

	private ConfigEntry<float> chestRoleUIPositionZ;

	private bool configWindowVisible;

	private bool chestManagementWindowVisible;

	private Rect chestManagementWindowRect = new Rect(0f, 0f, 780f, 620f);

	private Vector2 chestManagementScrollPosition;

	private readonly Dictionary<string, Dictionary<string, Container>> cachedZoneContainerById = new Dictionary<string, Dictionary<string, Container>>(StringComparer.Ordinal);

	private readonly Dictionary<Type, MethodInfo> cookingFindCookableCache = new Dictionary<Type, MethodInfo>();

	private readonly Dictionary<Type, MethodInfo> cookingAllowedItemCache = new Dictionary<Type, MethodInfo>();

	private string chestManagementSelectedProduction = "";

	private Rect configWindowRect = new Rect(0f, 0f, 620f, 560f);

	private Vector2 configScrollPosition;

	private bool configCursorWasVisible;

	private CursorLockMode configCursorPreviousLockState;

	private bool configCursorStateSaved;

	private bool hadLocalPlayerLastFrame;

	private const float HotkeyHeartbeatInterval = 10f;

	private GUIStyle configWindowStyle;

	private GUIStyle configSectionStyle;

	private GUIStyle configLabelStyle;

	private GUIStyle configDescriptionStyle;

	private GUIStyle configValueStyle;

	private const float ConfigWindowWidth = 620f;

	private const float ConfigWindowHeight = 560f;

	private const float StructureScanRadius = 20f;

	private const float StructureConnectionDistance = 1.25f;

	private const float InitialStructureSearchDistance = 8f;

	private const float HouseWallToFloorDistance = 2.75f;

	private const float ZoneInset = 0.15f;

	private const float ZoneLineWidth = 0.045f;

	private const float ZoneTrimMax = 20f;

	private const string ResourcePanelName = "QualityLifeMod_HouseResourcePanel";

	private const string ResourceItemName = "QualityLifeMod_HouseResourceItem";

	private GameObject resourcePanelObject;

	private RectTransform resourcePanelRect;

	private GridLayoutGroup resourceGrid;

	private CanvasGroup resourcePanelCanvasGroup;

	private readonly Dictionary<string, GameObject> resourceUIItems = new Dictionary<string, GameObject>();

	private bool resourceUIDirty = true;

	private bool lastResourceUIHammerState;

	private string lastResourceUIState = "";

	private const float ResourceCellWidth = 72f;

	private const float ResourceCellHeight = 42f;

	private const int ResourceColumns = 6;

	private const string BuilderSelectorName = "QualityLifeMod_BuilderZoneSelector";

	private GameObject builderSelectorObject;

	private RectTransform builderSelectorRect;

	private CanvasGroup builderSelectorCanvasGroup;

	private Text builderSelectorTitle;

	private Text builderSelectorZoneText;

	private Transform builderRepairAnchor;

	private const string ChestRolePanelName = "QualityLifeMod_ChestRolePanel";

	private GameObject chestRolePanelObject;

	private RectTransform chestRolePanelRect;

	private CanvasGroup chestRolePanelCanvasGroup;

	private GameObject chestRoleNativeTextObject;

	private GameObject chestRoleNativeBoxObject;

	private GameObject chestRoleNativeWithdrawButtonObject;

	private GameObject chestRoleNativeDepositButtonObject;

	private GameObject chestRoleNativeWithdrawLabelObject;

	private GameObject chestRoleNativeDepositLabelObject;

	private Component chestRoleNativeWeightText;

	private RectTransform chestRoleNativeTextRect;

	private string chestRoleNativeTextContainerId;

	private string lastChestRoleContainerId;

	private string lastChestRoleUISignature;

	private const float ChestRolePanelWidth = 230f;

	private const float ChestRolePanelHeight = 92f;

	private string openProductionDropdownContainerId;

	private const float BuilderSelectorUpdateInterval = 0.25f;

	private MethodInfo cachedGetRightItemMethod;

	private bool cachedHammerState;

	private float nextHammerStateUpdate;

	private const float HammerStateUpdateInterval = 0.1f;

	private bool cachedBuilderStateResult;

	private SavedZone cachedBuilderStateZone;

	private Player cachedBuilderStatePlayer;

	private string cachedBuilderStateWorkbenchId;

	private bool cachedBuilderStateHammer;

	private float nextBuilderStateCheck;

	private const float BuilderStateCheckInterval = 0.2f;

	private readonly Dictionary<string, List<Container>> cachedZoneContainers = new Dictionary<string, List<Container>>();

	private readonly Dictionary<string, SavedZone> savedZones = new Dictionary<string, SavedZone>();

	private string loadedWorldId;

	private string loadedPlayerId;

	private bool loadedForCurrentWorld;

	private float nextWorldLoadRetry;

	private int worldLoadRetryCount;

	private string forcedZoneLoadPath;

	private bool forcedZoneLoadIgnorePlayer;

	private const int MaxWorldLoadRetries = 12;

	private const float WorldLoadRetryInterval = 1f;

	private string selectedBuilderZoneWorkbenchId;

	private string managementZoneWorkbenchId;

	private GameObject zoneObject;

	private LineRenderer zoneRenderer;

	private string visibleZoneWorkbenchId;

	private List<Container> chestManagementCachedContainers;

	private string chestManagementCachedZoneId;

	private string lastCraftingStationRefreshId;

	private float lastCraftingStationRefreshTime = -999f;

	private const float craftingStationRefreshDebounceSeconds = 0.35f;

	private ConfigEntryBase pendingShortcutEntry;

	private bool pendingShortcutCapture;

	internal static ManualLogSource Log
	{
		get
		{
			if (!((Object)(object)Instance != (Object)null))
			{
				return null;
			}
			return ((BaseUnityPlugin)Instance).Logger;
		}
	}

	private string SaveDirectory => Path.Combine(Paths.ConfigPath, "Custom.qualitylife.mod");

	private string LegacySaveFilePath => Path.Combine(SaveDirectory, "house_zones.json");

	private string SaveFilePath
	{
		get
		{
			string worldId = ((!string.IsNullOrEmpty(loadedWorldId)) ? loadedWorldId : GetCurrentWorldId());
			string playerId = ((!string.IsNullOrEmpty(loadedPlayerId)) ? loadedPlayerId : GetCurrentPlayerId());
			return GetSaveFilePathForIdentity(worldId, playerId);
		}
	}

	internal void ScheduleChestRoleUIRefresh(Container chest)
	{
		try
		{
			if (!((Object)(object)chest == (Object)null))
			{
				((MonoBehaviour)this).StartCoroutine(ChestRoleUIEndOfFrameRefresh(chest));
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogWarning((object)("[QLM CHEST UI] Failed to schedule one-shot refresh | " + ex.Message));
			}
		}
	}

	private IEnumerator ChestRoleUIEndOfFrameRefresh(Container chest)
	{
		yield return (object)new WaitForEndOfFrame();
		if ((Object)(object)chest == (Object)null)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogWarning((object)"[QLM CHEST UI] One-shot refresh cancelled | Chest was destroyed.");
			}
		}
		else
		{
			RefreshChestRoleUIOnce(chest);
		}
	}

	internal void RefreshChestRoleUIOnce(Container chestOverride = null)
	{
		try
		{
			Container val = (((Object)(object)chestOverride != (Object)null) ? chestOverride : GetOpenContainer());
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)"[QLM CHEST UI] UI NOT SHOWN | No open chest/container was available.");
				}
				HideChestRoleUI();
				return;
			}
			Type type = AccessTools.TypeByName("InventoryGui");
			object obj = ((type == null) ? null : GetInventoryGuiInstance(type));
			if ((Object)(object)((obj == null) ? null : GetChestInventoryPanel(obj)) == (Object)null)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"[QLM CHEST UI] UI NOT SHOWN | InventoryGui.m_container panel was not found.");
				}
				HideChestRoleUI();
				return;
			}
			SavedZone savedZone = FindZoneForContainer(val);
			if (savedZone == null)
			{
				ManualLogSource log3 = Log;
				if (log3 != null)
				{
					log3.LogWarning((object)"[QLM CHEST UI] UI NOT SHOWN | Chest is not inside a saved House Zone.");
				}
				HideChestRoleUI();
				return;
			}
			string containerId = GetContainerId(val);
			if (string.IsNullOrEmpty(containerId))
			{
				ManualLogSource log4 = Log;
				if (log4 != null)
				{
					log4.LogWarning((object)"[QLM CHEST UI] UI NOT SHOWN | Could not resolve chest ZDO ID.");
				}
				HideChestRoleUI();
				return;
			}
			bool withdraw = savedZone.priorityContainerIds != null && savedZone.priorityContainerIds.Contains(containerId);
			bool deposit = savedZone.depositContainerIds != null && savedZone.depositContainerIds.Contains(containerId);
			string text = GetContainerDisplayLabel(savedZone, val, deposit: false);
			string text2 = GetContainerDisplayLabel(savedZone, val, deposit: true);
			if (string.Equals(text, "Unassigned", StringComparison.OrdinalIgnoreCase))
			{
				text = "";
			}
			if (string.Equals(text2, "Unassigned", StringComparison.OrdinalIgnoreCase))
			{
				text2 = "";
			}
			QualityLifeContainerSaveData containerSettings = GetContainerSettings(savedZone, containerId, create: false);
			string production = ((containerSettings == null || string.IsNullOrEmpty(containerSettings.productionCategory)) ? "All" : containerSettings.productionCategory);
			string text3 = containerId + "|" + withdraw + "|" + deposit + "|" + ((containerSettings == null) ? "" : (containerSettings.withdrawLabel + "|" + containerSettings.depositLabel + "|" + containerSettings.productionCategory));
			if (!string.Equals(text3, lastChestRoleUISignature, StringComparison.Ordinal))
			{
				UpdateNativeChestRoleText(savedZone, val, containerId, text3, withdraw, deposit, production, text, text2);
			}
			else if ((Object)(object)chestRoleNativeTextObject != (Object)null)
			{
				chestRoleNativeTextObject.SetActive(true);
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log5 = Log;
			if (log5 != null)
			{
				log5.LogWarning((object)("Chest role UI update failed: " + ex.Message));
			}
			HideChestRoleUI();
		}
	}

	private void UpdateNativeChestRoleText(SavedZone zone, Container chest, string id, string signature, bool withdraw, bool deposit, string production, string withdrawLabel, string depositLabel)
	{
		//IL_0454: Unknown result type (might be due to invalid IL or missing references)
		//IL_0459: Unknown result type (might be due to invalid IL or missing references)
		//IL_071a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0724: Expected O, but got Unknown
		//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ee: Expected O, but got Unknown
		//IL_0766: Unknown result type (might be due to invalid IL or missing references)
		//IL_0770: Expected O, but got Unknown
		//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
		//IL_0255: Unknown result type (might be due to invalid IL or missing references)
		//IL_027f: Unknown result type (might be due to invalid IL or missing references)
		//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ce: Expected O, but got Unknown
		//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_02f6: Expected O, but got Unknown
		//IL_07e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_07f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_080a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0833: Unknown result type (might be due to invalid IL or missing references)
		//IL_083f: Unknown result type (might be due to invalid IL or missing references)
		//IL_084b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0850: Unknown result type (might be due to invalid IL or missing references)
		//IL_0864: Unknown result type (might be due to invalid IL or missing references)
		//IL_0882: Unknown result type (might be due to invalid IL or missing references)
		//IL_088e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0893: Unknown result type (might be due to invalid IL or missing references)
		//IL_08b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0992: Unknown result type (might be due to invalid IL or missing references)
		//IL_09ac: Unknown result type (might be due to invalid IL or missing references)
		//IL_09c6: Unknown result type (might be due to invalid IL or missing references)
		//IL_09e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a0b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a1b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a20: Unknown result type (might be due to invalid IL or missing references)
		//IL_0a34: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Type type = AccessTools.TypeByName("InventoryGui");
			object obj = ((type == null) ? null : GetInventoryGuiInstance(type));
			if (obj == null)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)"[QLM CHEST UI] NATIVE UI NOT SHOWN | InventoryGui instance unavailable.");
				}
				HideChestRoleUI();
				return;
			}
			Component val = FindContainerWeightText(obj, null);
			if ((Object)(object)val == (Object)null)
			{
				GameObject chestInventoryPanel = GetChestInventoryPanel(obj);
				val = FindContainerWeightText(obj, chestInventoryPanel);
			}
			if ((Object)(object)val == (Object)null)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"[QLM CHEST UI] NATIVE UI NOT SHOWN | Could not resolve the chest inventory weight text.");
				}
				HideChestRoleUI();
				return;
			}
			Transform transform = val.transform;
			RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if ((Object)(object)val2 == (Object)null || (Object)(object)((Transform)val2).parent == (Object)null)
			{
				ManualLogSource log3 = Log;
				if (log3 != null)
				{
					log3.LogWarning((object)"[QLM CHEST UI] NATIVE UI NOT SHOWN | Chest weight RectTransform/parent unavailable.");
				}
				HideChestRoleUI();
				return;
			}
			RectTransform val3 = (((Object)(object)chestRoleNativeBoxObject == (Object)null) ? null : chestRoleNativeBoxObject.GetComponent<RectTransform>());
			if ((Object)(object)chestRoleNativeTextObject == (Object)null || (Object)(object)chestRoleNativeBoxObject == (Object)null)
			{
				if ((Object)(object)chestRoleNativeTextObject != (Object)null)
				{
					Object.Destroy((Object)(object)chestRoleNativeTextObject);
				}
				chestRoleNativeTextObject = Object.Instantiate<GameObject>(val.gameObject, ((Transform)val2).parent);
				((Object)chestRoleNativeTextObject).name = "QualityLifeMod_ChestRoleNativeText";
				ref RectTransform reference = ref chestRoleNativeTextRect;
				Transform transform2 = chestRoleNativeTextObject.transform;
				reference = (RectTransform)(object)((transform2 is RectTransform) ? transform2 : null);
				chestRoleNativeWeightText = FindTextComponentOnClone(chestRoleNativeTextObject);
				GameObject chestInventoryPanel2 = GetChestInventoryPanel(obj);
				GameObject val4 = FindNativeInventoryButtonTemplate(chestInventoryPanel2);
				Component val5 = FindNativeInventoryBackground(chestInventoryPanel2);
				if ((Object)(object)val4 == (Object)null)
				{
					ManualLogSource log4 = Log;
					if (log4 != null)
					{
						log4.LogWarning((object)"[QLM CHEST UI] NATIVE UI NOT SHOWN | No native inventory button template found.");
					}
					HideChestRoleUI();
					return;
				}
				chestRoleNativeBoxObject = new GameObject("QualityLifeMod_ChestRoleNativeBox");
				chestRoleNativeBoxObject.transform.SetParent(((Transform)val2).parent, false);
				val3 = chestRoleNativeBoxObject.AddComponent<RectTransform>();
				Image val6 = chestRoleNativeBoxObject.AddComponent<Image>();
				((Graphic)val6).raycastTarget = false;
				Image val7 = (Image)(object)((val5 is Image) ? val5 : null);
				if (val7 != null)
				{
					val6.sprite = val7.sprite;
					((Graphic)val6).material = ((Graphic)val7).material;
					val6.type = val7.type;
					val6.fillCenter = val7.fillCenter;
					val6.preserveAspect = val7.preserveAspect;
					((Graphic)val6).color = ((Graphic)val7).color;
				}
				else
				{
					((Graphic)val6).color = new Color(0.055f, 0.055f, 0.055f, 0.92f);
				}
				chestRoleNativeWithdrawButtonObject = CreateNativeChestRoleButton(((Transform)val2).parent, val4, "W", withdraw, (UnityAction)delegate
				{
					TogglePriorityContainerFromManagement(zone, chest);
					lastChestRoleUISignature = null;
					RefreshChestRoleUIOnce(chest);
				});
				chestRoleNativeDepositButtonObject = CreateNativeChestRoleButton(((Transform)val2).parent, val4, "D", deposit, (UnityAction)delegate
				{
					ToggleDepositContainerFromManagement(zone, chest);
					lastChestRoleUISignature = null;
					RefreshChestRoleUIOnce(chest);
				});
				if ((Object)(object)chestRoleNativeWithdrawButtonObject == (Object)null || (Object)(object)chestRoleNativeDepositButtonObject == (Object)null)
				{
					ManualLogSource log5 = Log;
					if (log5 != null)
					{
						log5.LogWarning((object)"[QLM CHEST UI] NATIVE UI NOT SHOWN | Failed to clone native inventory buttons.");
					}
					HideChestRoleUI();
					return;
				}
				chestRoleNativeBoxObject.SetActive(false);
			}
			if ((Object)(object)chestRoleNativeTextRect == (Object)null || (Object)(object)chestRoleNativeWeightText == (Object)null)
			{
				ManualLogSource log6 = Log;
				if (log6 != null)
				{
					log6.LogWarning((object)"[QLM CHEST UI] NATIVE UI NOT SHOWN | Could not clone the chest weight text component.");
				}
				HideChestRoleUI();
				return;
			}
			string value = "<color=#D8D8D8>Productions</color>\n" + production;
			PropertyInfo property = ((object)chestRoleNativeWeightText).GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
			if (property == null || !property.CanWrite)
			{
				ManualLogSource log7 = Log;
				if (log7 != null)
				{
					log7.LogWarning((object)"[QLM CHEST UI] NATIVE UI NOT SHOWN | Native chest weight text has no writable text property.");
				}
				HideChestRoleUI();
				return;
			}
			property.SetValue(chestRoleNativeWeightText, value, null);
			PropertyInfo property2 = ((object)chestRoleNativeWeightText).GetType().GetProperty("alignment", BindingFlags.Instance | BindingFlags.Public);
			if (property2 != null && property2.CanWrite && property2.PropertyType.IsEnum)
			{
				try
				{
					object value2 = Enum.Parse(property2.PropertyType, "TopLeft", ignoreCase: true);
					property2.SetValue(chestRoleNativeWeightText, value2, null);
				}
				catch
				{
				}
			}
			Rect rect = val2.rect;
			float num = ((Rect)(ref rect)).width + 70f;
			float num2 = 86f;
			try
			{
				PropertyInfo property3 = ((object)chestRoleNativeWeightText).GetType().GetProperty("preferredWidth", BindingFlags.Instance | BindingFlags.Public);
				PropertyInfo property4 = ((object)chestRoleNativeWeightText).GetType().GetProperty("preferredHeight", BindingFlags.Instance | BindingFlags.Public);
				if (property3 != null && property3.GetValue(chestRoleNativeWeightText, null) is float num3)
				{
					num = Mathf.Max(num, num3 + 18f);
				}
				if (property4 != null && property4.GetValue(chestRoleNativeWeightText, null) is float num4)
				{
					num2 = Mathf.Max(num2, num4 + 12f);
				}
			}
			catch
			{
			}
			SetNativeButtonText(chestRoleNativeWithdrawButtonObject, "W", withdraw);
			SetNativeButtonText(chestRoleNativeDepositButtonObject, "D", deposit);
			float num5 = 32f;
			float num6 = 22f;
			ConfigureNativeChestRoleButtonPosition(chestRoleNativeWithdrawButtonObject, num5, num6, 0f);
			ConfigureNativeChestRoleButtonPosition(chestRoleNativeDepositButtonObject, num5, num6, 0f - num6 - 2f);
			if ((Object)(object)chestRoleNativeWithdrawLabelObject == (Object)null || (Object)(object)chestRoleNativeBoxObject == (Object)null || (Object)(object)chestRoleNativeWithdrawLabelObject.transform.parent != (Object)(object)chestRoleNativeBoxObject.transform)
			{
				if ((Object)(object)chestRoleNativeWithdrawLabelObject != (Object)null)
				{
					Object.Destroy((Object)(object)chestRoleNativeWithdrawLabelObject);
				}
				chestRoleNativeWithdrawLabelObject = Object.Instantiate<GameObject>(val.gameObject, ((Transform)val2).parent);
				((Object)chestRoleNativeWithdrawLabelObject).name = "QualityLifeMod_ChestRoleWithdrawLabel";
			}
			if ((Object)(object)chestRoleNativeDepositLabelObject == (Object)null || (Object)(object)chestRoleNativeBoxObject == (Object)null || (Object)(object)chestRoleNativeDepositLabelObject.transform.parent != (Object)(object)chestRoleNativeBoxObject.transform)
			{
				if ((Object)(object)chestRoleNativeDepositLabelObject != (Object)null)
				{
					Object.Destroy((Object)(object)chestRoleNativeDepositLabelObject);
				}
				chestRoleNativeDepositLabelObject = Object.Instantiate<GameObject>(val.gameObject, ((Transform)val2).parent);
				((Object)chestRoleNativeDepositLabelObject).name = "QualityLifeMod_ChestRoleDepositLabel";
			}
			SetNativeLabelText(chestRoleNativeWithdrawLabelObject, withdrawLabel, withdraw);
			SetNativeLabelText(chestRoleNativeDepositLabelObject, depositLabel, deposit);
			ConfigureNativeChestRoleLabelPosition(chestRoleNativeWithdrawLabelObject, num5 + 6f, 0f);
			ConfigureNativeChestRoleLabelPosition(chestRoleNativeDepositLabelObject, num5 + 6f, 0f - num6 - 2f);
			Button val8 = (((Object)(object)chestRoleNativeWithdrawButtonObject == (Object)null) ? null : chestRoleNativeWithdrawButtonObject.GetComponent<Button>());
			if ((Object)(object)val8 != (Object)null)
			{
				((UnityEventBase)val8.onClick).RemoveAllListeners();
				((UnityEvent)val8.onClick).AddListener((UnityAction)delegate
				{
					TogglePriorityContainerFromManagement(zone, chest);
					lastChestRoleUISignature = null;
					RefreshChestRoleUIOnce(chest);
				});
			}
			Button val9 = (((Object)(object)chestRoleNativeDepositButtonObject == (Object)null) ? null : chestRoleNativeDepositButtonObject.GetComponent<Button>());
			if ((Object)(object)val9 != (Object)null)
			{
				((UnityEventBase)val9.onClick).RemoveAllListeners();
				((UnityEvent)val9.onClick).AddListener((UnityAction)delegate
				{
					ToggleDepositContainerFromManagement(zone, chest);
					lastChestRoleUISignature = null;
					RefreshChestRoleUIOnce(chest);
				});
			}
			float num7 = Mathf.Max(34f, num2);
			float num8 = num6 * 2f + 2f + num7 + 14f;
			float num9 = ((chestRoleUIPositionX == null) ? 0f : chestRoleUIPositionX.Value);
			float num10 = ((chestRoleUIPositionY == null) ? (-34f) : (chestRoleUIPositionY.Value - 34f));
			if ((Object)(object)val3 != (Object)null)
			{
				val3.anchorMin = val2.anchorMin;
				val3.anchorMax = val2.anchorMax;
				val3.pivot = new Vector2(0f, 1f);
				val3.sizeDelta = new Vector2(Mathf.Max(num5 + 72f, num + 12f), num8 + 8f);
				float x = val2.anchoredPosition.x;
				rect = val2.rect;
				float num11 = x + ((Rect)(ref rect)).width + 8f;
				float num12 = val2.anchoredPosition.y + 2f;
				val3.anchoredPosition = new Vector2(num11 + num9, num12 + num10);
				Vector3 localPosition = ((Transform)val3).localPosition;
				localPosition.z = ((chestRoleUIPositionZ == null) ? 0f : chestRoleUIPositionZ.Value);
				((Transform)val3).localPosition = localPosition;
				chestRoleNativeTextObject.transform.SetParent((Transform)(object)val3, false);
				chestRoleNativeWithdrawButtonObject.transform.SetParent((Transform)(object)val3, false);
				chestRoleNativeDepositButtonObject.transform.SetParent((Transform)(object)val3, false);
				chestRoleNativeWithdrawLabelObject.transform.SetParent((Transform)(object)val3, false);
				chestRoleNativeDepositLabelObject.transform.SetParent((Transform)(object)val3, false);
				ConfigureNativeChestRoleButtonPosition(chestRoleNativeWithdrawButtonObject, num5, num6, -6f);
				ConfigureNativeChestRoleButtonPosition(chestRoleNativeDepositButtonObject, num5, num6, 0f - num6 - 8f);
				ConfigureNativeChestRoleLabelPosition(chestRoleNativeWithdrawLabelObject, num5 + 12f, -6f);
				ConfigureNativeChestRoleLabelPosition(chestRoleNativeDepositLabelObject, num5 + 12f, 0f - num6 - 8f);
				chestRoleNativeTextRect.anchorMin = new Vector2(0f, 1f);
				chestRoleNativeTextRect.anchorMax = new Vector2(0f, 1f);
				chestRoleNativeTextRect.pivot = new Vector2(0f, 1f);
				chestRoleNativeTextRect.sizeDelta = new Vector2(Mathf.Max(num5 + 12f, num), num7);
				chestRoleNativeTextRect.anchoredPosition = new Vector2(6f, (0f - num6) * 2f - 14f);
				Vector3 localPosition2 = ((Transform)chestRoleNativeTextRect).localPosition;
				localPosition2.z = 0f;
				((Transform)chestRoleNativeTextRect).localPosition = localPosition2;
			}
			if ((Object)(object)val3 != (Object)null)
			{
				int siblingIndex = ((Transform)val2).GetSiblingIndex() + 1;
				chestRoleNativeBoxObject.transform.SetSiblingIndex(siblingIndex);
				chestRoleNativeBoxObject.SetActive(true);
			}
			chestRoleNativeWithdrawButtonObject.SetActive(true);
			chestRoleNativeDepositButtonObject.SetActive(true);
			chestRoleNativeWithdrawLabelObject.SetActive(true);
			chestRoleNativeDepositLabelObject.SetActive(true);
			chestRoleNativeTextObject.SetActive(true);
			PropertyInfo property5 = ((object)chestRoleNativeWeightText).GetType().GetProperty("raycastTarget", BindingFlags.Instance | BindingFlags.Public);
			if (property5 != null && property5.CanWrite && property5.PropertyType == typeof(bool))
			{
				property5.SetValue(chestRoleNativeWeightText, false, null);
			}
			lastChestRoleContainerId = id;
			lastChestRoleUISignature = signature;
			chestRoleNativeTextContainerId = id;
			lastChestRoleContainerId = id;
			lastChestRoleUISignature = signature;
			chestRoleNativeTextContainerId = id;
		}
		catch (Exception ex)
		{
			ManualLogSource log8 = Log;
			if (log8 != null)
			{
				log8.LogWarning((object)("[QLM CHEST UI] NATIVE UI UPDATE FAILED | " + ex));
			}
			HideChestRoleUI();
		}
	}

	private GameObject CreateNativeChestRoleButton(Transform parent, GameObject nativeButtonTemplate, string initialText, bool active, UnityAction action)
	{
		if ((Object)(object)parent == (Object)null || (Object)(object)nativeButtonTemplate == (Object)null)
		{
			return null;
		}
		GameObject val = Object.Instantiate<GameObject>(nativeButtonTemplate, parent);
		((Object)val).name = "QualityLifeMod_ChestRoleButton";
		Button val2 = val.GetComponent<Button>();
		if ((Object)(object)val2 == (Object)null)
		{
			val2 = val.GetComponentInChildren<Button>(true);
		}
		if ((Object)(object)val2 == (Object)null)
		{
			Object.Destroy((Object)(object)val);
			return null;
		}
		((UnityEventBase)val2.onClick).RemoveAllListeners();
		if (action != null)
		{
			((UnityEvent)val2.onClick).AddListener(action);
		}
		SetNativeButtonText(val, initialText, active);
		ConfigureNativeChestRoleButtonObject(val, initialText, active);
		return val;
	}

	private GameObject FindNativeInventoryButtonTemplate(GameObject containerPanel)
	{
		if ((Object)(object)containerPanel == (Object)null)
		{
			return null;
		}
		Button[] componentsInChildren = containerPanel.GetComponentsInChildren<Button>(true);
		string[] array = new string[6] { "TakeAll", "Take All", "Sort", "Split", "Drop", "Button" };
		Button[] array2;
		foreach (string value in array)
		{
			array2 = componentsInChildren;
			foreach (Button val in array2)
			{
				if (!((Object)(object)val == (Object)null) && !((Object)(object)((Component)val).gameObject == (Object)null) && ((Object)((Component)val).gameObject).name.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
				{
					return ((Component)val).gameObject;
				}
			}
		}
		array2 = componentsInChildren;
		foreach (Button val2 in array2)
		{
			if (!((Object)(object)val2 == (Object)null) && !((Object)(object)((Component)val2).gameObject == (Object)null) && ((Object)(object)((Selectable)val2).targetGraphic != (Object)null || (Object)(object)((Component)val2).GetComponent<Image>() != (Object)null))
			{
				return ((Component)val2).gameObject;
			}
		}
		return null;
	}

	private Component FindNativeInventoryBackground(GameObject containerPanel)
	{
		//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)containerPanel == (Object)null)
		{
			return null;
		}
		Image component = containerPanel.GetComponent<Image>();
		if ((Object)(object)component != (Object)null)
		{
			return (Component)(object)component;
		}
		Image[] componentsInChildren = containerPanel.GetComponentsInChildren<Image>(true);
		Image result = null;
		float num = 0f;
		Image[] array = componentsInChildren;
		foreach (Image val in array)
		{
			if ((Object)(object)val == (Object)null || (Object)(object)((Component)val).gameObject == (Object)null)
			{
				continue;
			}
			if (((Object)((Component)val).gameObject).name.IndexOf("background", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)((Component)val).gameObject).name.IndexOf("bg", StringComparison.OrdinalIgnoreCase) >= 0)
			{
				return (Component)(object)val;
			}
			Transform transform = ((Component)val).transform;
			RectTransform val2 = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if (!((Object)(object)val2 == (Object)null))
			{
				Rect rect = val2.rect;
				float width = ((Rect)(ref rect)).width;
				rect = val2.rect;
				float num2 = Mathf.Abs(width * ((Rect)(ref rect)).height);
				if (num2 > num)
				{
					num = num2;
					result = val;
				}
			}
		}
		return (Component)(object)result;
	}

	private void SetNativeLabelText(GameObject labelObject, string text, bool active)
	{
		if ((Object)(object)labelObject == (Object)null)
		{
			return;
		}
		SetNativeButtonText(labelObject, string.IsNullOrEmpty(text) ? "" : text, active);
		Component[] componentsInChildren = labelObject.GetComponentsInChildren<Component>(true);
		foreach (Component val in componentsInChildren)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			PropertyInfo property = ((object)val).GetType().GetProperty("raycastTarget", BindingFlags.Instance | BindingFlags.Public);
			if (property != null && property.CanWrite && property.PropertyType == typeof(bool))
			{
				try
				{
					property.SetValue(val, false, null);
				}
				catch
				{
				}
			}
		}
	}

	private void ConfigureNativeChestRoleLabelPosition(GameObject labelObject, float x, float y)
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: 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_0077: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)labelObject == (Object)null))
		{
			Transform transform = labelObject.transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if (!((Object)(object)val == (Object)null))
			{
				val.anchorMin = new Vector2(0f, 1f);
				val.anchorMax = new Vector2(0f, 1f);
				val.pivot = new Vector2(0f, 1f);
				val.sizeDelta = new Vector2(220f, 22f);
				val.anchoredPosition = new Vector2(x, y);
			}
		}
	}

	private void SetNativeButtonText(GameObject buttonObject, string text, bool active)
	{
		//IL_016d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0166: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Unknown result type (might be due to invalid IL or missing references)
		//IL_010d: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)buttonObject == (Object)null)
		{
			return;
		}
		Component[] componentsInChildren = buttonObject.GetComponentsInChildren<Component>(true);
		foreach (Component val in componentsInChildren)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			PropertyInfo property = ((object)val).GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
			if (property == null || !property.CanWrite || property.PropertyType != typeof(string))
			{
				continue;
			}
			string text2 = null;
			try
			{
				text2 = property.GetValue(val, null) as string;
			}
			catch
			{
			}
			if (text2 == null && ((object)val).GetType().Name.IndexOf("Text", StringComparison.OrdinalIgnoreCase) < 0)
			{
				continue;
			}
			try
			{
				property.SetValue(val, text, null);
				PropertyInfo property2 = ((object)val).GetType().GetProperty("color", BindingFlags.Instance | BindingFlags.Public);
				if (property2 != null && property2.CanWrite && property2.PropertyType == typeof(Color))
				{
					property2.SetValue(val, (object)(Color)(active ? Color.white : new Color(0.65f, 0.65f, 0.65f, 1f)), null);
				}
				return;
			}
			catch
			{
			}
		}
		Text componentInChildren = buttonObject.GetComponentInChildren<Text>(true);
		if ((Object)(object)componentInChildren != (Object)null)
		{
			componentInChildren.text = text;
			((Graphic)componentInChildren).color = (Color)(active ? Color.white : new Color(0.65f, 0.65f, 0.65f, 1f));
		}
	}

	private float GetNativeButtonPreferredWidth(GameObject buttonObject)
	{
		if ((Object)(object)buttonObject == (Object)null)
		{
			return 0f;
		}
		Component[] componentsInChildren = buttonObject.GetComponentsInChildren<Component>(true);
		float num = 0f;
		Component[] array = componentsInChildren;
		foreach (Component val in array)
		{
			if ((Object)(object)val == (Object)null || ((object)val).GetType().Name.IndexOf("Text", StringComparison.OrdinalIgnoreCase) < 0)
			{
				continue;
			}
			PropertyInfo property = ((object)val).GetType().GetProperty("preferredWidth", BindingFlags.Instance | BindingFlags.Public);
			if (property == null)
			{
				continue;
			}
			try
			{
				if (property.GetValue(val, null) is float num2)
				{
					num = Mathf.Max(num, num2);
				}
			}
			catch
			{
			}
		}
		return num;
	}

	private void ConfigureNativeChestRoleButtonPosition(GameObject buttonObject, float width, float height, float y)
	{
		//IL_002b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0055: Unknown result type (might be due to invalid IL or missing references)
		//IL_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)buttonObject == (Object)null))
		{
			Transform transform = buttonObject.transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if (!((Object)(object)val == (Object)null))
			{
				val.anchorMin = new Vector2(0f, 1f);
				val.anchorMax = new Vector2(0f, 1f);
				val.pivot = new Vector2(0f, 1f);
				val.sizeDelta = new Vector2(width, height);
				val.anchoredPosition = new Vector2(0f, y);
			}
		}
	}

	private void ConfigureNativeChestRoleButton(GameObject buttonObject, string text, Color backgroundColor, float width, float height, float y)
	{
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0054: Unknown result type (might be due to invalid IL or missing references)
		//IL_0063: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00df: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		//IL_0108: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)buttonObject == (Object)null))
		{
			Transform transform = buttonObject.transform;
			RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null);
			if ((Object)(object)val != (Object)null)
			{
				val.anchorMin = new Vector2(0f, 1f);
				val.anchorMax = new Vector2(0f, 1f);
				val.pivot = new Vector2(0f, 1f);
				val.sizeDelta = new Vector2(width, height);
				val.anchoredPosition = new Vector2(0f, y);
			}
			Image component = buttonObject.GetComponent<Image>();
			if ((Object)(object)component != (Object)null)
			{
				((Graphic)component).color = backgroundColor;
				((Graphic)component).raycastTarget = true;
			}
			Text component2 = buttonObject.GetComponent<Text>();
			if ((Object)(object)component2 != (Object)null)
			{
				component2.text = text;
				((Graphic)component2).color = Color.white;
				component2.alignment = (TextAnchor)3;
				((Graphic)component2).raycastTarget = false;
				RectTransform rectTransform = ((Graphic)component2).rectTransform;
				rectTransform.anchorMin = Vector2.zero;
				rectTransform.anchorMax = Vector2.one;
				rectTransform.offsetMin = new Vector2(8f, 0f);
				rectTransform.offsetMax = new Vector2(-4f, 0f);
			}
		}
	}

	private void ConfigureNativeChestRoleButtonObject(GameObject buttonObject, string initialText, bool active)
	{
		if (!((Object)(object)buttonObject == (Object)null))
		{
			SetNativeButtonText(buttonObject, initialText, active);
		}
	}

	private Component FindContainerWeightText(object inventoryGui, GameObject containerPanel)
	{
		try
		{
			if (inventoryGui == null)
			{
				return null;
			}
			string[] array = new string[3] { "m_containerWeight", "m_weightContainer", "m_containerWeightText" };
			foreach (string name in array)
			{
				FieldInfo field = inventoryGui.GetType().GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
				if (!(field == null))
				{
					object? value = field.GetValue(inventoryGui);
					Component val = (Component)((value is Component) ? value : null);
					if ((Object)(object)val != (Object)null)
					{
						return val;
					}
				}
			}
			if ((Object)(object)containerPanel == (Object)null)
			{
				return null;
			}
			Component[] componentsInChildren = containerPanel.GetComponentsInChildren<Component>(true);
			foreach (Component val2 in componentsInChildren)
			{
				if (!((Object)(object)val2 == (Object)null) && (((Object)(object)val2.gameObject == (Object)null) ? "" : ((Object)val2.gameObject).name).IndexOf("weight", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					PropertyInfo property = ((object)val2).GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
					if (property != null && property.PropertyType == typeof(string) && property.CanWrite)
					{
						return val2;
					}
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogWarning((object)("[QLM CHEST UI] Failed to resolve chest weight text | " + ex.Message));
			}
		}
		return null;
	}

	private Component FindTextComponentOnClone(GameObject clone)
	{
		if ((Object)(object)clone == (Object)null)
		{
			return null;
		}
		try
		{
			Component[] components = clone.GetComponents<Component>();
			foreach (Component val in components)
			{
				if (!((Object)(object)val == (Object)null))
				{
					PropertyInfo property = ((object)val).GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public);
					if (property != null && property.PropertyType == typeof(string) && property.CanWrite)
					{
						return val;
					}
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private void EnsureChestRolePanel(GameObject inventoryPanel)
	{
		//IL_0057: Unknown result type (might be due to invalid IL or missing references)
		//IL_0061: Expected O, but got Unknown
		//IL_0099: Unknown result type (might be due to invalid IL or missing references)
		//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0144: Unknown result type (might be due to invalid IL or missing references)
		//IL_014e: Expected O, but got Unknown
		if ((Object)(object)chestRolePanelObject != (Object)null && (Object)(object)chestRolePanelObject.transform.parent == (Object)(object)inventoryPanel.transform)
		{
			chestRolePanelObject.SetActive(true);
			return;
		}
		if ((Object)(object)chestRolePanelObject != (Object)null)
		{
			Object.Destroy((Object)(object)chestRolePanelObject);
		}
		chestRolePanelObject = new GameObject("QualityLifeMod_ChestRolePanel");
		chestRolePanelObject.transform.SetParent(inventoryPanel.transform, false);
		chestRolePanelRect = chestRolePanelObject.AddComponent<RectTransform>();
		chestRolePanelRect.anchorMin = new Vector2(0.5f, 0.5f);
		chestRolePanelRect.anchorMax = new Vector2(0.5f, 0.5f);
		chestRolePanelRect.pivot = new Vector2(0.5f, 0.5f);
		chestRolePanelRect.sizeDelta = new Vector2(230f, 92f);
		chestRolePanelCanvasGroup = chestRolePanelObject.AddComponent<CanvasGroup>();
		chestRolePanelCanvasGroup.alpha = 1f;
		chestRolePanelObject.transform.SetAsLastSibling();
		VerticalLayoutGroup obj = chestRolePanelObject.AddComponent<VerticalLayoutGroup>();
		((LayoutGroup)obj).childAlignment = (TextAnchor)1;
		((HorizontalOrVerticalLayoutGroup)obj).spacing = 2f;
		((LayoutGroup)obj).padding = new RectOffset(4, 4, 4, 4);
		((HorizontalOrVerticalLayoutGroup)obj).childControlWidth = true;
		((HorizontalOrVerticalLayoutGroup)obj).childControlHeight = false;
		((HorizontalOrVerticalLayoutGroup)obj).childForceExpandWidth = true;
		((HorizontalOrVerticalLayoutGroup)obj).childForceExpandHeight = false;
	}

	private void PositionChestRolePanel()
	{
		//IL_0068: 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)
		//IL_007d: Unknown result type (might be due to invalid IL or missing references)
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)chestRolePanelRect == (Object)null))
		{
			float num = ((chestRoleUIPositionX != null) ? chestRoleUIPositionX.Value : 0f);
			float num2 = ((chestRoleUIPositionY != null) ? chestRoleUIPositionY.Value : 0f);
			float z = ((chestRoleUIPositionZ != null) ? chestRoleUIPositionZ.Value : 0f);
			chestRolePanelRect.anchoredPosition = new Vector2(num, num2);
			Vector3 localPosition = ((Transform)chestRolePanelRect).localPosition;
			localPosition.z = z;
			((Transform)chestRolePanelRect).localPosition = localPosition;
		}
	}

	private void UpdateChestRolePanel(SavedZone zone, Container chest, string id, string signature)
	{
		//IL_003c: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ff: Expected O, but got Unknown
		//IL_0131: Unknown result type (might be due to invalid IL or missing references)
		//IL_013b: Expected O, but got Unknown
		if ((Object)(object)chestRolePanelObject == (Object)null)
		{
			return;
		}
		foreach (Transform item in chestRolePanelObject.transform)
		{
			Object.Destroy((Object)(object)((Component)item).gameObject);
		}
		bool withdraw = zone.priorityContainerIds != null && zone.priorityContainerIds.Contains(id);
		bool deposit = zone.depositContainerIds != null && zone.depositContainerIds.Contains(id);
		QualityLifeContainerSaveData containerSettings = GetContainerSettings(zone, id, create: true);
		CreateChestRoleText(chestRolePanelObject.transform, "Quality Life", 18, (FontStyle)1);
		CreateChestRoleButton(chestRolePanelObject.transform, "WITHDRAW - " + GetContainerDisplayLabel(zone, chest, deposit: false), withdraw, (UnityAction)delegate
		{
			TogglePriorityContainer(chest, withdraw);
		});
		CreateChestRoleButton(chestRolePanelObject.transform, "DEPOSIT - " + GetContainerDisplayLabel(zone, chest, deposit: true), deposit, (UnityAction)delegate
		{
			ToggleDepositContainer(chest, deposit);
		});
		CreateChestRoleText(chestRolePanelObject.transform, string.IsNullOrEmpty(containerSettings.productionCategory) ? "Production: All" : ("Production: " + containerSettings.productionCategory), 12, (FontStyle)0);
		lastChestRoleContainerId = id;
		lastChestRoleUISignature = signature;
		chestRolePanelObject.SetActive(true);
	}

	private Text CreateChestRoleText(Transform parent, string value, int size, FontStyle style)
	{
		//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_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_002a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0058: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Text");
		val.transform.SetParent(parent, false);
		val.AddComponent<RectTransform>().sizeDelta = new Vector2(230f, (float)size + 10f);
		Text obj = val.AddComponent<Text>();
		obj.text = value;
		obj.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
		obj.fontSize = size;
		obj.fontStyle = style;
		obj.alignment = (TextAnchor)4;
		return obj;
	}

	private Button CreateChestRoleButton(Transform parent, string value, bool active, UnityAction action)
	{
		//IL_0005: Unknown result type (might be due to invalid IL or missing references)
		//IL_000b: Expected O, but got Unknown
		//IL_0028: 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_004f: Unknown result type (might be due to invalid IL or missing references)
		GameObject val = new GameObject("Button");
		val.transform.SetParent(parent, false);
		val.AddComponent<RectTransform>().sizeDelta = new Vector2(230f, 26f);
		((Graphic)val.AddComponent<Image>()).color = (active ? new Color(0.2f, 0.55f, 0.25f, 0.9f) : new Color(0.18f, 0.18f, 0.18f, 0.9f));
		Button obj = val.AddComponent<Button>();
		((UnityEvent)obj.onClick).AddListener(action);
		CreateChestRoleText(val.transform, value, 13, (FontStyle)1);
		return obj;
	}

	private void HideChestRoleUI()
	{
		if ((Object)(object)chestRolePanelObject != (Object)null)
		{
			chestRolePanelObject.SetActive(false);
		}
		if ((Object)(object)chestRoleNativeTextObject != (Object)null)
		{
			chestRoleNativeTextObject.SetActive(false);
		}
		if ((Object)(object)chestRoleNativeBoxObject != (Object)null)
		{
			chestRoleNativeBoxObject.SetActive(false);
		}
		if ((Object)(object)chestRoleNativeWithdrawButtonObject != (Object)null)
		{
			chestRoleNativeWithdrawButtonObject.SetActive(false);
		}
		if ((Object)(object)chestRoleNativeDepositButtonObject != (Object)null)
		{
			chestRoleNativeDepositButtonObject.SetActive(false);
		}
		if ((Object)(object)chestRoleNativeWithdrawLabelObject != (Object)null)
		{
			chestRoleNativeWithdrawLabelObject.SetActive(false);
		}
		if ((Object)(object)chestRoleNativeDepositLabelObject != (Object)null)
		{
			chestRoleNativeDepositLabelObject.SetActive(false);
		}
		lastChestRoleContainerId = null;
		lastChestRoleUISignature = null;
		chestRoleNativeTextContainerId = null;
		openProductionDropdownContainerId = null;
	}

	private string GetSaveFilePathForIdentity(string worldId, string playerId)
	{
		return LegacySaveFilePath;
	}

	private string SanitizeFilePart(string value)
	{
		if (string.IsNullOrEmpty(value))
		{
			return "Unknown";
		}
		char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
		foreach (char c in invalidFileNameChars)
		{
			value = value.Replace(c.ToString(), "_");
		}
		return value;
	}

	private void Awake()
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Expected O, but got Unknown
		//IL_0030: 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_008e: 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_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_0124: Unknown result type (might be due to invalid IL or missing references)
		//IL_0159: 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_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e6: Unknown result type (might be due to invalid IL or missing references)
		//IL_021b: Unknown result type (might be due to invalid IL or missing references)
		Instance = this;
		Harmony = new Harmony("Custom.qualitylife.mod");
		try
		{
			configMenuHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ConfigMenuHotkey", new KeyboardShortcut((KeyCode)282, Array.Empty<KeyCode>()), "Hotkey used to open or close the Quality Life Mod configuration window.");
			chestManagementMenuHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "ChestManagementMenuHotkey", new KeyboardShortcut((KeyCode)285, Array.Empty<KeyCode>()), "Hotkey used to open or close the chest and production management window.");
			loadHouseZonesHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("House Zones", "LoadZonesHotkey", new KeyboardShortcut((KeyCode)283, Array.Empty<KeyCode>()), "Hotkey used to manually reload the saved house zones for the current world.");
			createHouseZoneHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("House Zones", "CreateZoneHotkey", new KeyboardShortcut((KeyCode)122, Array.Empty<KeyCode>()), "Hotkey used at a crafting station to create or rebuild its house zone.");
			builderZoneHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Builder", "HouseZoneHotkey", new KeyboardShortcut((KeyCode)122, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Hotkey used to cycle through saved house zones while holding the hammer.");
			deleteSelectedZoneHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("House Zones", "DeleteSelectedZoneHotkey", new KeyboardShortcut((KeyCode)120, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Hotkey used to delete the currently selected house zone while holding the hammer.");
			deleteAllZonesHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("House Zones", "DeleteAllZonesHotkey", new KeyboardShortcut((KeyCode)99, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Hotkey used to delete all saved house zones while holding the hammer.");
			priorityInputChestHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Priority Chests", "PriorityInputChestHotkey", new KeyboardShortcut((KeyCode)122, Array.Empty<KeyCode>()), "With a chest open, marks the chest as a priority input chest for production/refining stations.");
			priorityInputChestRemoveHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Priority Chests", "PriorityInputChestRemoveHotkey", new KeyboardShortcut((KeyCode)122, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "With a chest open, removes its priority input role.");
			priorityDepositChestHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Priority Chests", "PriorityDepositChestHotkey", new KeyboardShortcut((KeyCode)110, Array.Empty<KeyCode>()), "With a chest open, marks the chest as an automatic production-output destination.");
			priorityDepositChestRemoveHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Priority Chests", "PriorityDepositChestRemoveHotkey", new KeyboardShortcut((KeyCode)110, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "With a chest open, removes its automatic production-output destination role.");
			chestRoleUIPositionX = ((BaseUnityPlugin)this).Config.Bind<float>("Chest Role UI", "PositionX", 0f, "Horizontal screen position of the chest role UI. 0 = centered; positive values move right; negative values move left.");
			chestRoleUIPositionY = ((BaseUnityPlugin)this).Config.Bind<float>("Chest Role UI", "PositionY", 0f, "Vertical screen position of the chest role UI. 0 = centered; positive values move up; negative values move down.");
			chestRoleUIPositionZ = ((BaseUnityPlugin)this).Config.Bind<float>("Chest Role UI", "PositionZ", 0f, "UI depth of the chest role panel. 0 is the default centered UI depth.");
			Harmony.PatchAll();
			PatchPlacedPiece();
			PatchPlayerConsumeResources();
			PatchPriorityProductionStations();
			PatchPriorityProductionOutput();
			PatchSleepAutomation();
			PatchAchievements();
			PatchPlayerHaveRequirements();
			Initialized = true;
		}
		catch (Exception ex)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)("Failed to initialize Quality Life Mod: " + ex));
			}
		}
	}

	private void PatchAchievements()
	{
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		//IL_006e: Expected O, but got Unknown
		try
		{
			MethodInfo methodInfo = AccessTools.Method(typeof(Achievements), "IsCheatedAtAll", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)"Could not find Achievements.IsCheatedAtAll(). Steam achievement patch was not installed.");
				}
			}
			else
			{
				MethodInfo methodInfo2 = AccessTools.Method(typeof(AchievementModdedPatch), "Prefix", (Type[])null, (Type[])null);
				if (!(methodInfo2 == null))
				{
					Harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log2 = Log;
			if (log2 != null)
			{
				log2.LogError((object)("Failed to patch Steam achievements: " + ex));
			}
		}
	}

	private void PatchPlayerConsumeResources()
	{
		//IL_0106: Unknown result type (might be due to invalid IL or missing references)
		//IL_0114: Expected O, but got Unknown
		try
		{
			MethodInfo methodInfo = null;
			MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			foreach (MethodInfo methodInfo2 in methods)
			{
				if (!(methodInfo2.Name != "ConsumeResources"))
				{
					ParameterInfo[] parameters = methodInfo2.GetParameters();
					if (parameters.Length == 4 && !(parameters[0].ParameterType != typeof(Requirement[])) && !(parameters[1].ParameterType != typeof(int)) && !(parameters[2].ParameterType != typeof(int)) && !(parameters[3].ParameterType != typeof(int)))
					{
						methodInfo = methodInfo2;
						break;
					}
				}
			}
			if (methodInfo == null)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)"Could not find Player.ConsumeResources(Requirement[], int, int, int). House-resource consumption patch was not installed.");
				}
			}
			else
			{
				MethodInfo methodInfo3 = AccessTools.Method(typeof(PlayerConsumeResourcesPatch), "Prefix", (Type[])null, (Type[])null);
				if (!(methodInfo3 == null))
				{
					Harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log2 = Log;
			if (log2 != null)
			{
				log2.LogError((object)("Failed to patch Player.ConsumeResources: " + ex));
			}
		}
	}

	private void PatchPlayerHaveRequirements()
	{
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d0: Expected O, but got Unknown
		//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Expected O, but got Unknown
		try
		{
			MethodInfo methodInfo = null;
			MethodInfo[] methods = typeof(Player).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			MethodInfo[] array = methods;
			foreach (MethodInfo methodInfo2 in array)
			{
				if (!(methodInfo2.Name != "HaveRequirements"))
				{
					ParameterInfo[] parameters = methodInfo2.GetParameters();
					if (parameters.Length >= 1 && !(parameters[0].ParameterType != typeof(Piece)))
					{
						methodInfo = methodInfo2;
						break;
					}
				}
			}
			if (methodInfo == null)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)"Could not find Player.HaveRequirements(Piece...). Builder resource patch was not installed.");
				}
				return;
			}
			MethodInfo methodInfo3 = AccessTools.Method(typeof(PlayerHaveRequirementsPatch), "Postfix", (Type[])null, (Type[])null);
			if (methodInfo3 == null)
			{
				return;
			}
			Harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo3), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			MethodInfo methodInfo4 = null;
			array = methods;
			foreach (MethodInfo methodInfo5 in array)
			{
				if (!(methodInfo5.Name != "HaveRequirements"))
				{
					ParameterInfo[] parameters2 = methodInfo5.GetParameters();
					if (parameters2.Length == 4 && !(parameters2[0].ParameterType != typeof(Recipe)) && !(parameters2[1].ParameterType != typeof(bool)) && !(parameters2[2].ParameterType != typeof(int)) && !(parameters2[3].ParameterType != typeof(int)))
					{
						methodInfo4 = methodInfo5;
						break;
					}
				}
			}
			if (methodInfo4 != null)
			{
				MethodInfo methodInfo6 = AccessTools.Method(typeof(PlayerHaveRecipeRequirementsPatch), "Postfix", (Type[])null, (Type[])null);
				if (methodInfo6 != null)
				{
					Harmony.Patch((MethodBase)methodInfo4, (HarmonyMethod)null, new HarmonyMethod(methodInfo6), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
				}
			}
			else
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"Could not find Player.HaveRequirements(Recipe,bool,int,int). Crafting GUI house-resource patch was not installed.");
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log3 = Log;
			if (log3 != null)
			{
				log3.LogError((object)("Failed to patch Player.HaveRequirements: " + ex));
			}
		}
	}

	private void Update()
	{
		//IL_0020: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_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_0084: Unknown result type (might be due to invalid IL or missing references)
		//IL_0089: Unknown result type (might be due to invalid IL or missing references)
		//IL_0162: Unknown result type (might be due to invalid IL or missing references)
		//IL_0167: Unknown result type (might be due to invalid IL or missing references)
		//IL_0182: Unknown result type (might be due to invalid IL or missing references)
		//IL_0187: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0269: Unknown result type (might be due to invalid IL or missing references)
		//IL_026e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0288: Unknown result type (might be due to invalid IL or missing references)
		//IL_028d: Unknown result type (might be due to invalid IL or missing references)
		//IL_02a9: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ae: Unknown result type (might be due to invalid IL or missing references)
		//IL_02ca: Unknown result type (might be due to invalid IL or missing references)
		//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			if (!Initialized)
			{
				return;
			}
			EnsureWorldLoaded();
			KeyboardShortcut value;
			if (configMenuHotkey != null)
			{
				value = configMenuHotkey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					if (chestManagementWindowVisible)
					{
						ToggleChestManagementWindow();
					}
					ToggleConfigWindow();
				}
			}
			if (chestManagementMenuHotkey != null)
			{
				value = chestManagementMenuHotkey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					if (configWindowVisible)
					{
						ToggleConfigWindow();
					}
					ToggleChestManagementWindow();
				}
			}
			if (loadHouseZonesHotkey != null)
			{
				value = loadHouseZonesHotkey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					ForceReloadHouseZones();
				}
			}
			if (configWindowVisible)
			{
				UnlockConfigCursor();
				HideResourceUI();
				HideChestRoleUI();
				HideBuilderSelector();
				return;
			}
			if (chestManagementWindowVisible)
			{
				UnlockConfigCursor();
				HideResourceUI();
				HideChestRoleUI();
				HideBuilderSelector();
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				hadLocalPlayerLastFrame = false;
				HideResourceUI();
				HideBuilderSelector();
				return;
			}
			if (!hadLocalPlayerLastFrame)
			{
				InvalidateAllZoneContainerCaches();
				InvalidateBuilderStateCache();
				if (!string.IsNullOrEmpty(selectedBuilderZoneWorkbenchId) && savedZones.TryGetValue(selectedBuilderZoneWorkbenchId, out var value2) && value2 != null)
				{
					ShowZone(value2);
				}
				hadLocalPlayerLastFrame = true;
			}
			int num;
			if (priorityInputChestRemoveHotkey != null)
			{
				value = priorityInputChestRemoveHotkey.Value;
				num = (((KeyboardShortcut)(ref value)).IsDown() ? 1 : 0);
			}
			else
			{
				num = 0;
			}
			bool flag = (byte)num != 0;
			int num2;
			if (priorityInputChestHotkey != null)
			{
				value = priorityInputChestHotkey.Value;
				num2 = (((KeyboardShortcut)(ref value)).IsDown() ? 1 : 0);
			}
			else
			{
				num2 = 0;
			}
			bool flag2 = (byte)num2 != 0;
			int num3;
			if (priorityDepositChestRemoveHotkey != null)
			{
				value = priorityDepositChestRemoveHotkey.Value;
				num3 = (((KeyboardShortcut)(ref value)).IsDown() ? 1 : 0);
			}
			else
			{
				num3 = 0;
			}
			bool flag3 = (byte)num3 != 0;
			int num4;
			if (priorityDepositChestHotkey != null)
			{
				value = priorityDepositChestHotkey.Value;
				num4 = (((KeyboardShortcut)(ref value)).IsDown() ? 1 : 0);
			}
			else
			{
				num4 = 0;
			}
			bool flag4 = (byte)num4 != 0;
			Container val = null;
			if (flag || flag2 || flag3 || flag4)
			{
				val = GetOpenContainer();
			}
			bool flag5 = false;
			if ((Object)(object)val != (Object)null && flag)
			{
				TogglePriorityContainer(val, remove: true);
				flag5 = true;
			}
			else if ((Object)(object)val != (Object)null && flag2)
			{
				TogglePriorityContainer(val, remove: false);
				flag5 = true;
			}
			else if ((Object)(object)val != (Object)null && flag3)
			{
				ToggleDepositContainer(val, remove: true);
				flag5 = true;
			}
			else if ((Object)(object)val != (Object)null && flag4)
			{
				ToggleDepositContainer(val, remove: false);
				flag5 = true;
			}
			if (!flag5)
			{
				int num5;
				if (createHouseZoneHotkey != null)
				{
					value = createHouseZoneHotkey.Value;
					num5 = (((KeyboardShortcut)(ref value)).IsDown() ? 1 : 0);
				}
				else
				{
					num5 = 0;
				}
				int num6;
				if (deleteSelectedZoneHotkey != null)
				{
					value = deleteSelectedZoneHotkey.Value;
					num6 = (((KeyboardShortcut)(ref value)).IsDown() ? 1 : 0);
				}
				else
				{
					num6 = 0;
				}
				bool flag6 = (byte)num6 != 0;
				int num7;
				if (deleteAllZonesHotkey != null)
				{
					value = deleteAllZonesHotkey.Value;
					num7 = (((KeyboardShortcut)(ref value)).IsDown() ? 1 : 0);
				}
				else
				{
					num7 = 0;
				}
				bool flag7 = (byte)num7 != 0;
				int num8;
				if (builderZoneHotkey != null)
				{
					value = builderZoneHotkey.Value;
					num8 = (((KeyboardShortcut)(ref value)).IsDown() ? 1 : 0);
				}
				else
				{
					num8 = 0;
				}
				bool flag8 = (byte)num8 != 0;
				if (num5 != 0)
				{
					HandleZoneHotkey();
				}
				if (flag6)
				{
					HandleDeleteSelectedZoneHotkey();
				}
				if (flag7)
				{
					HandleDeleteAllZonesHotkey();
				}
				if (flag8)
				{
					HandleBuilderZoneHotkey();
				}
			}
			bool flag9 = IsHoldingHammer(localPlayer);
			if (flag9 != lastResourceUIHammerState)
			{
				lastResourceUIHammerState = flag9;
				resourceUIDirty = true;
			}
			if (flag9)
			{
				HideResourceUI();
				HideBuilderSelector();
				resourceUIDirty = false;
				return;
			}
			if (resourceUIDirty)
			{
				resourceUIDirty = false;
				UpdateHouseResourceUI();
			}
			HideBuilderSelector();
		}
		catch (Exception ex)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)("Update error: " + ex));
			}
		}
	}

	private void HandleDeleteSelectedZoneHotkey()
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null || !IsHoldingHammerImmediate(localPlayer))
		{
			return;
		}
		if (string.IsNullOrEmpty(selectedBuilderZoneWorkbenchId))
		{
			ShowNativeMessage(GetLocalizedMessage("No selected house zone."));
			return;
		}
		string text = selectedBuilderZoneWorkbenchId;
		if (!savedZones.ContainsKey(text))
		{
			selectedBuilderZoneWorkbenchId = null;
			InvalidateBuilderStateCache();
			HideZone();
			SaveZones();
			return;
		}
		savedZones.Remove(text);
		if (string.Equals(managementZoneWorkbenchId, text, StringComparison.Ordinal))
		{
			managementZoneWorkbenchId = null;
		}
		InvalidateZoneContainerCache(text);
		if (visibleZoneWorkbenchId == text)
		{
			HideZone();
		}
		List<SavedZone> orderedSavedZones = GetOrderedSavedZones();
		if (orderedSavedZones.Count > 0 && orderedSavedZones[0] != null)
		{
			selectedBuilderZoneWorkbenchId = orderedSavedZones[0].workbenchId;
		}
		else
		{
			selectedBuilderZoneWorkbenchId = null;
		}
		InvalidateBuilderStateCache();
		SaveZones(savedZones.Count == 0);
		ShowNativeMessage(GetLocalizedMessage("Selected house zone deleted."));
		if (!string.IsNullOrEmpty(selectedBuilderZoneWorkbenchId) && savedZones.TryGetValue(selectedBuilderZoneWorkbenchId, out var value) && value != null)
		{
			ShowZone(value);
		}
	}

	private void HandleDeleteAllZonesHotkey()
	{
		Player localPlayer = Player.m_localPlayer;
		if (!((Object)(object)localPlayer == (Object)null) && IsHoldingHammerImmediate(localPlayer))
		{
			if (savedZones.Count == 0)
			{
				ShowNativeMessage(GetLocalizedMessage("No saved house zones."));
				return;
			}
			savedZones.Clear();
			managementZoneWorkbenchId = null;
			InvalidateAllZoneContainerCaches();
			selectedBuilderZoneWorkbenchId = null;
			InvalidateBuilderStateCache();
			HideZone();
			SaveZones(allowEmptyOverwrite: true);
			ShowNativeMessage(GetLocalizedMessage("All house zones deleted."));
		}
	}

	private void HandleBuilderZoneHotkey()
	{
		Player localPlayer = Player.m_localPlayer;
		if ((Object)(object)localPlayer == (Object)null)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogWarning((object)"Builder hotkey pressed, but local player is null.");
			}
		}
		else if (IsHoldingHammerImmediate(localPlayer))
		{
			CycleBuilderZone();
		}
	}

	private void CycleBuilderZone()
	{
		if (!loadedForCurrentWorld)
		{
			EnsureWorldLoaded();
		}
		if (savedZones.Count == 0)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogWarning((object)("Builder hotkey pressed, but no saved house zones are loaded for this world. File: " + SaveFilePath));
			}
			ShowNativeMessage(GetLocalizedMessage("No saved house zones."));
			return;
		}
		List<SavedZone> orderedSavedZones = GetOrderedSavedZones();
		if (orderedSavedZones.Count == 0)
		{
			return;
		}
		int num = -1;
		if (!string.IsNullOrEmpty(selectedBuilderZoneWorkbenchId))
		{
			for (int i = 0; i < orderedSavedZones.Count; i++)
			{
				if (orderedSavedZones[i] != null && orderedSavedZones[i].workbenchId == selectedBuilderZoneWorkbenchId)
				{
					num = i;
					break;
				}
			}
		}
		int index = ((num >= 0) ? ((num + 1) % orderedSavedZones.Count) : 0);
		SavedZone savedZone = orderedSavedZones[index];
		if (savedZone != null)
		{
			selectedBuilderZoneWorkbenchId = savedZone.workbenchId;
			InvalidateBuilderStateCache();
			GetContainersInsideZone(savedZone);
			SaveZones();
			ShowZone(savedZone);
		}
	}

	private List<SavedZone> GetOrderedSavedZones()
	{
		List<SavedZone> list = new List<SavedZone>();
		foreach (KeyValuePair<string, SavedZone> savedZone in savedZones)
		{
			if (savedZone.Value != null)
			{
				list.Add(savedZone.Value);
			}
		}
		list.Sort(delegate(SavedZone a, SavedZone b)
		{
			if (a == null && b == null)
			{
				return 0;
			}
			if (a == null)
			{
				return 1;
			}
			return (b == null) ? (-1) : string.Compare(a.workbenchId, b.workbenchId, StringComparison.Ordinal);
		});
		return list;
	}

	internal static bool IsBuilderZoneCraftingActive(Player player, out SavedZone zone)
	{
		zone = null;
		if ((Object)(object)Instance == (Object)null || (Object)(object)player == (Object)null)
		{
			return false;
		}
		return Instance.GetCachedBuilderZoneState(player, out zone);
	}

	private bool GetCachedBuilderZoneState(Player player, out SavedZone zone)
	{
		zone = null;
		if ((Object)(object)player == (Object)null)
		{
			return false;
		}
		if ((Object)(object)player.GetCurrentCraftingStation() != (Object)null)
		{
			cachedBuilderStatePlayer = player;
			cachedBuilderStateHammer = false;
			cachedBuilderStateWorkbenchId = selectedBuilderZoneWorkbenchId;
			cachedBuilderStateZone = null;
			cachedBuilderStateResult = false;
			nextBuilderStateCheck = Time.unscaledTime + 0.2f;
			return false;
		}
		bool flag = IsHoldingHammer(player);
		string text = selectedBuilderZoneWorkbenchId;
		if (Time.unscaledTime < nextBuilderStateCheck && (Object)(object)cachedBuilderStatePlayer == (Object)(object)player && cachedBuilderStateHammer == flag && string.Equals(cachedBuilderStateWorkbenchId, text, StringComparison.Ordinal))
		{
			zone = cachedBuilderStateZone;
			return cachedBuilderStateResult;
		}
		nextBuilderStateCheck = Time.unscaledTime + 0.2f;
		cachedBuilderStatePlayer = player;
		cachedBuilderStateHammer = flag;
		cachedBuilderStateWorkbenchId = text;
		cachedBuilderStateZone = null;
		if (!flag || string.IsNullOrEmpty(text))
		{
			cachedBuilderStateResult = false;
			return false;
		}
		if (!savedZones.TryGetValue(text, out var value) || value == null)
		{
			cachedBuilderStateResult = false;
			return false;
		}
		cachedBuilderStateZone = value;
		cachedBuilderStateResult = true;
		zone = value;
		return true;
	}

	private void InvalidateBuilderStateCache()
	{
		nextBuilderStateCheck = 0f;
		cachedBuilderStateResult = false;
		cachedBuilderStateZone = null;
		cachedBuilderStatePlayer = null;
		cachedBuilderStateWorkbenchId = null;
		cachedBuilderStateHammer = false;
	}

	internal void MarkResourceUIDirty()
	{
		resourceUIDirty = true;
	}

	internal void ResetCraftingRecipeResourceUI()
	{
		resourceUIDirty = false;
		HideResourceUI();
	}

	internal void HideResourceUIFromEvent()
	{
		HideResourceUI();
		resourceUIDirty = false;
	}

	private void UpdateHouseResourceUI()
	{
		try
		{
			Type type = AccessTools.TypeByName("InventoryGui");
			if (type == null)
			{
				HideResourceUI();
				return;
			}
			object inventoryGuiInstance = GetInventoryGuiInstance(type);
			if (inventoryGuiInstance == null)
			{
				HideResourceUI();
				return;
			}
			GameObject inventoryScreen = GetInventoryScreen(inventoryGuiInstance);
			if ((Object)(object)inventoryScreen == (Object)null || !inventoryScreen.activeInHierarchy)
			{
				HideResourceUI();
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null)
			{
				HideResourceUI();
				return;
			}
			if (!IsZoneCraftingActive(localPlayer, out var _))
			{
				HideResourceUI();
				return;
			}
			object selectedRecipe = GetSelectedRecipe(inventoryGuiInstance);
			if (selectedRecipe == null)
			{
				HideResourceUI();
				return;
			}
			Recipe recipeFromRecipeDataPair = GetRecipeFromRecipeDataPair(selectedRecipe);
			if ((Object)(object)recipeFromRecipeDataPair == (Object)null)
			{
				HideResourceUI();
				return;
			}
			Dictionary<string, HouseResourceData> recipeHouseResources = GetRecipeHouseResources(recipeFromRecipeDataPair, localPlayer);
			if (recipeHouseResources.Count == 0)
			{
				HideResourceUI();
				return;
			}
			EnsureResourcePanel(inventoryScreen);
			PositionNormalResourcePanel();
			UpdateResourcePanel(recipeHouseResources);
		}
		catch (Exception ex)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogWarning((object)("House resource UI update failed: " + ex.Message));
			}
			HideResourceUI();
		}
	}

	private object GetInventoryGuiInstance(Type inventoryGuiType)
	{
		try
		{
			FieldInfo field = inventoryGuiType.GetField("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				object value = field.GetValue(null);
				if (value != null)
				{
					return value;
				}
			}
			PropertyInfo property = inventoryGuiType.GetProperty("instance", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null)
			{
				object value2 = property.GetValue(null, null);
				if (value2 != null)
				{
					return value2;
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private GameObject GetChestInventoryPanel(object inventoryGui)
	{
		try
		{
			FieldInfo field = inventoryGui.GetType().GetField("m_container", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogWarning((object)"[QLM CHEST UI] InventoryGui.m_container field was not found.");
				}
				return null;
			}
			object value = field.GetValue(inventoryGui);
			GameObject val = (GameObject)((value is GameObject) ? value : null);
			if (val != null)
			{
				return val;
			}
			RectTransform val2 = (RectTransform)((value is RectTransform) ? value : null);
			if (val2 != null)
			{
				return ((Component)val2).gameObject;
			}
			Transform val3 = (Transform)((value is Transform) ? value : null);
			if (val3 != null)
			{
				return ((Component)val3).gameObject;
			}
			Component val4 = (Component)((value is Component) ? value : null);
			if (val4 != null)
			{
				return val4.gameObject;
			}
			ManualLogSource log2 = Log;
			if (log2 != null)
			{
				log2.LogWarning((object)("[QLM CHEST UI] InventoryGui.m_container has unsupported type: " + ((value == null) ? "NULL" : value.GetType().FullName)));
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log3 = Log;
			if (log3 != null)
			{
				log3.LogWarning((object)("[QLM CHEST UI] Failed to resolve InventoryGui.m_container: " + ex.Message));
			}
		}
		return null;
	}

	private string GetTransformPath(Transform transform)
	{
		if ((Object)(object)transform == (Object)null)
		{
			return "NULL";
		}
		string text = ((Object)transform).name;
		Transform parent = transform.parent;
		int num = 0;
		while ((Object)(object)parent != (Object)null && num++ < 20)
		{
			text = ((Object)parent).name + "/" + text;
			parent = parent.parent;
		}
		return text;
	}

	private GameObject GetInventoryScreen(object inventoryGui)
	{
		//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Type type = inventoryGui.GetType();
			FieldInfo field = type.GetField("m_root", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				object value = field.GetValue(inventoryGui);
				GameObject val = (GameObject)((value is GameObject) ? value : null);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
				RectTransform val2 = (RectTransform)((value is RectTransform) ? value : null);
				if ((Object)(object)val2 != (Object)null)
				{
					return ((Component)val2).gameObject;
				}
			}
			field = type.GetField("m_inventoryRoot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				object value2 = field.GetValue(inventoryGui);
				GameObject val3 = (GameObject)((value2 is GameObject) ? value2 : null);
				if ((Object)(object)val3 != (Object)null)
				{
					return val3;
				}
				RectTransform val4 = (RectTransform)((value2 is RectTransform) ? value2 : null);
				if ((Object)(object)val4 != (Object)null)
				{
					return ((Component)val4).gameObject;
				}
			}
			Transform[] array = Resources.FindObjectsOfTypeAll<Transform>();
			foreach (Transform val5 in array)
			{
				if (!((Object)(object)val5 == (Object)null) && !(((Object)val5).name != "Inventory_screen"))
				{
					Scene scene = ((Component)val5).gameObject.scene;
					if (((Scene)(ref scene)).IsValid())
					{
						return ((Component)val5).gameObject;
					}
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private object GetSelectedRecipe(object inventoryGui)
	{
		try
		{
			FieldInfo field = inventoryGui.GetType().GetField("m_selectedRecipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field == null)
			{
				return null;
			}
			return field.GetValue(inventoryGui);
		}
		catch
		{
			return null;
		}
	}

	private Recipe GetRecipeFromRecipeDataPair(object selectedRecipe)
	{
		if (selectedRecipe == null)
		{
			return null;
		}
		try
		{
			Type type = selectedRecipe.GetType();
			FieldInfo field = type.GetField("Recipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null)
			{
				object? value = field.GetValue(selectedRecipe);
				Recipe val = (Recipe)((value is Recipe) ? value : null);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
			}
			PropertyInfo property = type.GetProperty("Recipe", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (property != null)
			{
				object? value2 = property.GetValue(selectedRecipe, null);
				Recipe val2 = (Recipe)((value2 is Recipe) ? value2 : null);
				if ((Object)(object)val2 != (Object)null)
				{
					return val2;
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private Dictionary<string, HouseResourceData> GetRecipeHouseResources(Recipe recipe, Player player)
	{
		Dictionary<string, HouseResourceData> dictionary = new Dictionary<string, HouseResourceData>();
		if ((Object)(object)recipe == (Object)null)
		{
			return dictionary;
		}
		if ((Object)(object)player == (Object)null)
		{
			return dictionary;
		}
		Requirement[] resources = recipe.m_resources;
		if (resources == null)
		{
			return dictionary;
		}
		List<Container> craftingContainers = GetCraftingContainers(player);
		if (craftingContainers == null || craftingContainers.Count == 0)
		{
			return dictionary;
		}
		Requirement[] array = resources;
		foreach (Requirement val in array)
		{
			if (val == null || (Object)(object)val.m_resItem == (Object)null)
			{
				continue;
			}
			if (val.m_upgraderResource)
			{
				CraftingStation currentCraftingStation = player.GetCurrentCraftingStation();
				if ((Object)(object)currentCraftingStation != (Object)null && !currentCraftingStation.m_upgrader)
				{
					continue;
				}
			}
			ItemDrop resItem = val.m_resItem;
			if (resItem.m_itemData == null || resItem.m_itemData.m_shared == null)
			{
				continue;
			}
			string name = resItem.m_itemData.m_shared.m_name;
			if (string.IsNullOrEmpty(name))
			{
				continue;
			}
			int num = CountItemInContainers(craftingContainers, name);
			if (num > 0)
			{
				if (dictionary.ContainsKey(name))
				{
					dictionary[name].amount += num;
					continue;
				}
				Sprite itemIcon = GetItemIcon(resItem);
				dictionary[name] = new HouseResourceData
				{
					itemName = name,
					amount = num,
					icon = itemIcon
				};
			}
		}
		return dictionary;
	}

	private int CountItemInContainers(List<Container> containers, string itemName)
	{
		if (containers == null)
		{
			return 0;
		}
		if (string.IsNullOrEmpty(itemName))
		{
			return 0;
		}
		int num = 0;
		foreach (Container container in containers)
		{
			if ((Object)(object)container == (Object)null)
			{
				continue;
			}
			try
			{
				Inventory inventory = container.GetInventory();
				if (inventory != null)
				{
					num += inventory.CountItems(itemName, -1, true);
				}
			}
			catch
			{
			}
		}
		return num;
	}

	private Sprite GetItemIcon(ItemDrop itemDrop)
	{
		if ((Object)(object)itemDrop == (Object)null)
		{
			return null;
		}
		try
		{
			if (itemDrop.m_itemData == null)
			{
				return null;
			}
			if (itemDrop.m_itemData.m_shared == null)
			{
				return null;
			}
			Sprite[] icons = itemDrop.m_itemData.m_shared.m_icons;
			if (icons != null && icons.Length != 0)
			{
				return icons[0];
			}
		}
		catch
		{
		}
		return null;
	}

	private void EnsureResourcePanel(GameObject inventoryScreen)
	{
		//IL_0068: Unknown result type (might be due to invalid IL or missing references)
		//IL_0072: Expected O, but got Unknown
		//IL_00aa: 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_00de: Unknown result type (might be due to invalid IL or missing references)
		//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
		//IL_0112: Unknown result type (might be due to invalid IL or missing references)
		//IL_013d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0157: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)inventoryScreen == (Object)null)
		{
			return;
		}
		if ((Object)(object)resourcePanelObject != (Object)null)
		{
			if ((Object)(object)resourcePanelObject.transform.parent == (Object)(object)inventoryScreen.transform)
			{
				resourcePanelObject.SetActive(true);
				return;
			}
			Object.Destroy((Object)(object)resourcePanelObject);
			resourcePanelObject = null;
			resourcePanelRect = null;
			resourceGrid = null;
		}
		resourcePanelObject = new GameObject("QualityLifeMod_HouseResourcePanel");
		resourcePanelObject.transform.SetParent(inventoryScreen.transform, false);
		resourcePanelRect = resourcePanelObject.AddComponent<RectTransform>();
		resourcePanelRect.anchorMin = new Vector2(0.5f, 0f);
		resourcePanelRect.anchorMax = new Vector2(0.5f, 0f);
		resourcePanelRect.pivot = new Vector2(0.5f, 0f);
		resourcePanelRect.anchoredPosition = new Vector2(0f, 145f);
		resourcePanelRect.sizeDelta = new Vector2(432f, 180f);
		resourceGrid = resourcePanelObject.AddComponent<GridLayoutGroup>();
		resourceGrid.cellSize = new Vector2(72f, 42f);
		resourceGrid.spacing = new Vector2(4f, 3f);
		resourceGrid.constraint = (Constraint)1;
		resourceGrid.constraintCount = 6;
		((LayoutGroup)resourceGrid).childAlignment = (TextAnchor)7;
		resourceGrid.startCorner = (Corner)0;
		resourceGrid.startAxis = (Axis)0;
		resourcePanelCanvasGroup = resourcePanelObject.AddComponent<CanvasGroup>();
		resourcePanelCanvasGroup.alpha = 1f;
		resourcePanelObject.SetActive(true);
	}

	private void UpdateResourcePanel(Dictionary<string, HouseResourceData> resources)
	{
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_016f: Unknown result type (might be due to invalid IL or missing references)
		//IL_017d: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)resourcePanelObject == (Object)null || (Object)(object)resourcePanelRect == (Object)null || (Object)(object)resourceGrid == (Object)null)
		{
			return;
		}
		if (resources == null || resources.Count == 0)
		{
			HideResourceUI();
			return;
		}
		string text = BuildResourceUIState(resources);
		if (text == lastResourceUIState)
		{
			resourcePanelObject.SetActive(true);
			return;
		}
		lastResourceUIState = text;
		List<HouseResourceData> list = new List<HouseResourceData>(resources.Values);
		list.Sort((HouseResourceData a, HouseResourceData b) => string.Compare(a.itemName, b.itemName, StringComparison.Ordinal));
		int count = list.Count;
		for (int num = 0; num < count; num++)
		{
			HouseResourceData data = list[num];
			GameObject orCreateResourceItem = GetOrCreateResourceItem(num);
			UpdateResourceItem(orCreateResourceItem, data);
		}
		for (int num2 = count; num2 < resourceUIItems.Count; num2++)
		{
			string key = "QualityLifeMod_HouseResourceItem_" + num2;
			if (resourceUIItems.TryGetValue(key, out var value) && (Object)(object)value != (Object)null)
			{
				value.SetActive(false);
			}
		}
		int num3 = Mathf.CeilToInt((float)count / 6f);
		num3 = Mathf.Max(1, num3);
		float num4 = (float)num3 * 42f + (float)Mathf.Max(0, num3 - 1) * resourceGrid.spacing.y;
		resourcePanelRect.sizeDelta = new Vector2(432f + 5f * resourceGrid.spacing.x, num4);
		resourcePanelObject.SetActive(true);
	}

	private string BuildResourceUIState(Dictionary<string, HouseResourceData> resources)
	{
		List<string> list = new List<string>();
		foreach (KeyValuePair<string, HouseResourceData> resource in resources)
		{
			if (resource.Value != null)
			{
				list.Add(resource.Key + ":" + resource.Value.amount);
			}
		}
		list.Sort(StringComparer.Ordinal);
		return string.Join("|", list.ToArray());
	}

	private string GetLocalizedBuilderContainersText(int count)
	{
		return GetCurrentLanguage() switch
		{
			"Portuguese_Brazilian" => "Baus: " + count, 
			"French" => "Coffres : " + count, 
			"Italian" => "Bauli: " + count, 
			"German" => "Truhen: " + count, 
			"Spanish" => "Cofres: " + count, 
			"Russian" => "Сундуки: " + count, 
			"Turkish" => "Sandık: " + count, 
			"Polish" => "Skrzynie: " + count, 
			"Chinese" => "箱子: " + count, 
			"Chinese_Trad" => "箱子: " + count, 
			"Japanese" => "チェスト: " + count, 
			"Korean" => "상자: " + count, 
			_ => "Chests: " + count, 
		};
	}

	private void UpdateBuilderResourceUI()
	{
		try
		{
			Type type = AccessTools.TypeByName("InventoryGui");
			if (type == null)
			{
				HideResourceUI();
				return;
			}
			object inventoryGuiInstance = GetInventoryGuiInstance(type);
			if (inventoryGuiInstance == null)
			{
				HideResourceUI();
				return;
			}
			GameObject inventoryScreen = GetInventoryScreen(inventoryGuiInstance);
			if ((Object)(object)inventoryScreen == (Object)null || !inventoryScreen.activeInHierarchy)
			{
				HideResourceUI();
				return;
			}
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				HideResourceUI();
				return;
			}
			if (string.IsNullOrEmpty(selectedBuilderZoneWorkbenchId) || !savedZones.TryGetValue(selectedBuilderZoneWorkbenchId, out var value) || value == null)
			{
				HideResourceUI();
				return;
			}
			object selectedRecipe = GetSelectedRecipe(inventoryGuiInstance);
			if (selectedRecipe == null)
			{
				HideResourceUI();
				return;
			}
			Recipe recipeFromRecipeDataPair = GetRecipeFromRecipeDataPair(selectedRecipe);
			if ((Object)(object)recipeFromRecipeDataPair == (Object)null)
			{
				HideResourceUI();
				return;
			}
			Dictionary<string, HouseResourceData> recipeHouseResourcesFromZone = GetRecipeHouseResourcesFromZone(recipeFromRecipeDataPair, value);
			if (recipeHouseResourcesFromZone.Count == 0)
			{
				HideResourceUI();
				return;
			}
			EnsureResourcePanel(inventoryScreen);
			PositionBuilderResourcePanel();
			UpdateResourcePanel(recipeHouseResourcesFromZone);
		}
		catch (Exception ex)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogWarning((object)("Builder resource UI update failed: " + ex.Message));
			}
			HideResourceUI();
		}
	}

	private Dictionary<string, HouseResourceData> GetRecipeHouseResourcesFromZone(Recipe recipe, SavedZone zone)
	{
		Dictionary<string, HouseResourceData> dictionary = new Dictionary<string, HouseResourceData>();
		if ((Object)(object)recipe == (Object)null || zone == null)
		{
			return dictionary;
		}
		Requirement[] resources = recipe.m_resources;
		if (resources == null)
		{
			return dictionary;
		}
		List<Container> priorityContainersInsideZone = GetPriorityContainersInsideZone(zone);
		if (priorityContainersInsideZone.Count == 0)
		{
			return dictionary;
		}
		Requirement[] array = resources;
		foreach (Requirement val in array)
		{
			if (val == null || (Object)(object)val.m_resItem == (Object)null || val.m_upgraderResource)
			{
				continue;
			}
			ItemDrop resItem = val.m_resItem;
			if (resItem.m_itemData == null || resItem.m_itemData.m_shared == null)
			{
				continue;
			}
			string name = resItem.m_itemData.m_shared.m_name;
			if (string.IsNullOrEmpty(name))
			{
				continue;
			}
			int num = CountItemInContainers(priorityContainersInsideZone, name);
			if (num > 0)
			{
				if (dictionary.ContainsKey(name))
				{
					dictionary[name].amount += num;
					continue;
				}
				dictionary[name] = new HouseResourceData
				{
					itemName = name,
					amount = num,
					icon = GetItemIcon(resItem)
				};
			}
		}
		return dictionary;
	}

	private void PositionNormalResourcePanel()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)resourcePanelRect == (Object)null))
		{
			resourcePanelRect.anchoredPosition = new Vector2(0f, 145f);
		}
	}

	private void PositionBuilderResourcePanel()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)resourcePanelRect == (Object)null))
		{
			resourcePanelRect.anchoredPosition = new Vector2(245f, 145f);
		}
	}

	private GameObject GetOrCreateResourceItem(int index)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0048: Expected O, but got Unknown
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0080: Unknown result type (might be due to invalid IL or missing references)
		//IL_0094: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a3: 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_00e5: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
		//IL_010f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0123: Unknown result type (might be due to invalid IL or missing references)
		//IL_0138: 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_017a: Unknown result type (might be due to invalid IL or missing references)
		//IL_018f: Unknown result type (might be due to invalid IL or missing references)
		//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b8: Unknown result type (might be due to invalid IL or missing references)
		//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
		string text = "QualityLifeMod_HouseResourceItem_" + index;
		if (resourceUIItems.TryGetValue(text, out var value))
		{
			if ((Object)(object)value != (Object)null)
			{
				value.SetActive(true);
				return value;
			}
			resourceUIItems.Remove(text);
		}
		value = new GameObject(text);
		value.transform.SetParent((Transform)(object)resourcePanelRect, false);
		RectTransform obj = value.AddComponent<RectTransform>();
		obj.anchorMin = new Vector2(0.5f, 0.5f);
		obj.anchorMax = new Vector2(0.5f, 0.5f);
		obj.pivot = new Vector2(0.5f, 0.5f);
		Image obj2 = new GameObject("Icon").AddComponent<Image>();
		((Component)obj2).transform.SetParent(value.transform, false);
		RectTransform rectTransform = ((Graphic)obj2).rectTransform;
		rectTransform.anchorMin = new Vector2(0f, 0.5f);
		rectTransform.anchorMax = new Vector2(0f, 0.5f);
		rectTransform.pivot = new Vector2(0f, 0.5f);
		rectTransform.anchoredPosition = new Vector2(2f, 0f);
		rectTransform.sizeDelta = new Vector2(32f, 32f);
		obj2.preserveAspect = true;
		Text obj3 = new GameObject("Quantity").AddComponent<Text>();
		((Component)obj3).transform.SetParent(value.transform, false);
		RectTransform rectTransform2 = ((Graphic)obj3).rectTransform;
		rectTransform2.anchorMin = new Vector2(0f, 0.5f);
		rectTransform2.anchorMax = new Vector2(0f, 0.5f);
		rectTransform2.pivot = new Vector2(0f, 0.5f);
		rectTransform2.anchoredPosition = new Vector2(38f, 0f);
		rectTransform2.sizeDelta = new Vector2(30f, 32f);
		obj3.alignment = (TextAnchor)3;
		obj3.fontSize = 16;
		obj3.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
		((Graphic)obj3).color = Color.white;
		obj3.supportRichText = false;
		resourceUIItems[text] = value;
		return value;
	}

	private void UpdateResourceItem(GameObject itemObject, HouseResourceData data)
	{
		if (!((Object)(object)itemObject == (Object)null) && data != null)
		{
			itemObject.SetActive(true);
			Transform obj = itemObject.transform.Find("Icon");
			Image val = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null);
			Transform obj2 = itemObject.transform.Find("Quantity");
			Text val2 = ((obj2 != null) ? ((Component)obj2).GetComponent<Text>() : null);
			if ((Object)(object)val != (Object)null)
			{
				val.sprite = data.icon;
				((Behaviour)val).enabled = (Object)(object)data.icon != (Object)null;
			}
			if ((Object)(object)val2 != (Object)null)
			{
				val2.text = data.amount.ToString();
			}
		}
	}

	private void HideResourceUI()
	{
		if ((Object)(object)resourcePanelObject != (Object)null)
		{
			resourcePanelObject.SetActive(false);
		}
		lastResourceUIState = "";
	}

	private void UpdateBuilderZoneSelector()
	{
		HideBuilderSelector();
	}

	private void UpdateBuilderSelectorImmediate()
	{
		HideBuilderSelector();
	}

	private Canvas FindActiveCanvas()
	{
		//IL_001f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0024: Unknown result type (might be due to invalid IL or missing references)
		//IL_003d: 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_0074: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			Canvas[] array = Resources.FindObjectsOfTypeAll<Canvas>();
			Canvas[] array2 = array;
			Scene scene;
			foreach (Canvas val in array2)
			{
				if (!((Object)(object)val == (Object)null))
				{
					scene = ((Component)val).gameObject.scene;
					if (((Scene)(ref scene)).IsValid() && ((Component)val).gameObject.activeInHierarchy && (int)val.renderMode == 0)
					{
						return val;
					}
				}
			}
			array2 = array;
			foreach (Canvas val2 in array2)
			{
				if (!((Object)(object)val2 == (Object)null))
				{
					scene = ((Component)val2).gameObject.scene;
					if (((Scene)(ref scene)).IsValid() && ((Component)val2).gameObject.activeInHierarchy)
					{
						return val2;
					}
				}
			}
		}
		catch
		{
		}
		return null;
	}

	private Transform FindRepairUI()
	{
		return null;
	}

	private void EnsureBuilderSelector()
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0036: Expected O, but got Unknown
		//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cb: 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_0135: 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_019a: Unknown result type (might be due to invalid IL or missing references)
		//IL_01af: Unknown result type (might be due to