Decompiled source of StorageVision v1.0.0

plugins/StorageVision.dll

Decompiled an hour ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using HighlightPlus;
using Rewired;
using StarterAssets;
using StorageVision.Core;
using StorageVision.Handlers;
using StorageVision.Patches;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("StorageVision")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+f5549865fff88b2c897902a50fdfa9b5e71e4d1c")]
[assembly: AssemblyProduct("StorageVision")]
[assembly: AssemblyTitle("StorageVision")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace StorageVision
{
	public enum OriginalPanelMode
	{
		MoveToCenter,
		Hide,
		Keep
	}
	public enum HighlightMode
	{
		LookedAt,
		OrderTarget,
		Both
	}
	public enum OrderValueMode
	{
		Payout,
		Market,
		ShelfPrice,
		All
	}
	internal sealed class MenuInfo
	{
		public readonly string Name;

		public MenuInfo(string name)
		{
			Name = name;
		}
	}
	internal static class ModConfig
	{
		public static ConfigFile File;

		public static readonly List<ConfigEntryBase> MenuEntries = new List<ConfigEntryBase>();

		public static ConfigEntry<KeyboardShortcut> MenuKey;

		public static ConfigEntry<bool> HudEnabled;

		public static ConfigEntry<float> HudFontSize;

		public static ConfigEntry<float> HudOffsetX;

		public static ConfigEntry<float> HudOffsetY;

		public static ConfigEntry<Color> HudTextColor;

		public static ConfigEntry<float> HudBackgroundOpacity;

		public static ConfigEntry<float> HudBackgroundPadding;

		public static ConfigEntry<OriginalPanelMode> OriginalPanel;

		public static ConfigEntry<float> OriginalPanelScale;

		public static ConfigEntry<float> ProductTextScale;

		public static ConfigEntry<bool> StorageEnabled;

		public static ConfigEntry<bool> StorageShowPrices;

		public static ConfigEntry<bool> HighlightEnabled;

		public static ConfigEntry<HighlightMode> HighlightModeEntry;

		public static ConfigEntry<Color> HighlightColor;

		public static ConfigEntry<float> HighlightWidth;

		public static ConfigEntry<bool> HighlightAlwaysOnTop;

		public static ConfigEntry<bool> HideOrderArrows;

		public static ConfigEntry<bool> WorkTableEnabled;

		public static ConfigEntry<OrderValueMode> WorkTableValueMode;

		public static ConfigEntry<int> WorkTableMaxItemLines;

		private static ConfigFile _cfg;

		public static void Bind(ConfigFile cfg)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0257: Unknown result type (might be due to invalid IL or missing references)
			File = cfg;
			_cfg = cfg;
			MenuKey = cfg.Bind<KeyboardShortcut>("0. General", "MenuKey", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Key that opens the in-game settings menu.");
			HudEnabled = Bind("1. Center HUD", "Enabled", value: true, "Show center info", "Turns on everything in the middle of the screen: the moved product panel, the background and the info text.");
			OriginalPanel = Bind("1. Center HUD", "OriginalPanel", OriginalPanelMode.MoveToCenter, "Game's product panel", "The game's own panel with product image, name and brand (normally top right). Move To Center = under the crosshair. Hide = remove it. Keep = leave it top right.");
			OriginalPanelScale = Bind("1. Center HUD", "OriginalPanelScale", 1f, "Product panel size", "Size of the game's product panel (image + name) when it is moved to the center.", 0.3f, 3f);
			ProductTextScale = Bind("1. Center HUD", "ProductTextScale", 1f, "Product name size", "Size of the product name and brand in the game's panel (e.g. \"Tropical Soda\" / \"Ropico\"), on top of the panel size. Only when the panel is moved to the center.", 0.5f, 3f);
			HudFontSize = Bind("1. Center HUD", "FontSize", 22f, "Info text size", "Size of the extra info text from this mod (box amount, prices, packing table info).", 10f, 60f);
			HudTextColor = Bind<Color>("1. Center HUD", "TextColor", Color.white, "Info text color", "Color of the extra info text.");
			HudBackgroundOpacity = Bind("1. Center HUD", "BackgroundOpacity", 0.6f, "Background darkness", "How dark the background box behind the center info is. 0 = no background.", 0f, 1f);
			HudBackgroundPadding = Bind("1. Center HUD", "BackgroundPadding", 6f, "Background padding", "Empty space between the content and the edge of the background box. Lower = tighter box.", 0f, 40f);
			HudOffsetX = Bind("1. Center HUD", "OffsetX", 0f, "Horizontal position", "Moves the center info left (negative) or right (positive) from the crosshair.", -800f, 800f);
			HudOffsetY = Bind("1. Center HUD", "OffsetY", -40f, "Vertical position", "Moves the center info up (positive) or down (negative). -40 = just below the crosshair.", -800f, 800f);
			StorageEnabled = Bind("2. Storage", "Enabled", value: false, "Show box amount text", "Adds a line under the product panel with how many items are in the storage box you look at (e.g. \"Box: 20 / 20\"). The outline works without this.");
			StorageShowPrices = Bind("2. Storage", "ShowPrices", value: true, "Include prices", "Adds your shelf price and the market price to that line.");
			HighlightEnabled = Bind("3. Highlight", "Enabled", value: true, "Outline boxes", "Draws a colored outline around a box.");
			HighlightModeEntry = Bind("3. Highlight", "Mode", HighlightMode.LookedAt, "Which box", "Looked At = the storage box under the crosshair. Order Target = while holding the order tray: the nearest box with the next product the online order needs. Both = the order target while picking an order, otherwise the box you look at.");
			HighlightColor = Bind<Color>("3. Highlight", "Color", Color.green, "Outline color", "Color of the outline.");
			HighlightWidth = Bind("3. Highlight", "Width", 0.8f, "Outline thickness", "How thick the outline is.", 0.1f, 3f);
			HighlightAlwaysOnTop = Bind("3. Highlight", "AlwaysOnTop", value: false, "Visible through objects", "Show the outline even where the box is hidden behind shelves or other boxes.");
			HideOrderArrows = Bind("3. Highlight", "HideOrderArrows", value: false, "Hide the game's order arrows", "Hides the game's green arrows above shelves while you pick online orders. Useful with Order Target.");
			WorkTableEnabled = Bind("4. Work table", "Enabled", value: true, "Show packing table info", "When you look at an online-order packing table: shows whether it has an order, what is left to pack and what it is worth.");
			WorkTableValueMode = Bind("4. Work table", "ValueMode", OrderValueMode.Payout, "Order value", "Payout = what the customer pays you at pickup (the game rolls 3.25-3.5x market price per item, so a range is shown). Market = market price. Shelf Price = at your own prices. All = all three.");
			WorkTableMaxItemLines = Bind("4. Work table", "MaxItemLines", 8, "Products listed", "How many products of the order to list (0 = no list).", 0, 40);
			MenuEntries.Clear();
			MenuEntries.AddRange((IEnumerable<ConfigEntryBase>)(object)new ConfigEntryBase[21]
			{
				(ConfigEntryBase)HudEnabled,
				(ConfigEntryBase)OriginalPanel,
				(ConfigEntryBase)OriginalPanelScale,
				(ConfigEntryBase)ProductTextScale,
				(ConfigEntryBase)HudFontSize,
				(ConfigEntryBase)HudTextColor,
				(ConfigEntryBase)HudBackgroundOpacity,
				(ConfigEntryBase)HudBackgroundPadding,
				(ConfigEntryBase)HudOffsetX,
				(ConfigEntryBase)HudOffsetY,
				(ConfigEntryBase)StorageEnabled,
				(ConfigEntryBase)StorageShowPrices,
				(ConfigEntryBase)HighlightEnabled,
				(ConfigEntryBase)HighlightModeEntry,
				(ConfigEntryBase)HighlightColor,
				(ConfigEntryBase)HighlightWidth,
				(ConfigEntryBase)HighlightAlwaysOnTop,
				(ConfigEntryBase)HideOrderArrows,
				(ConfigEntryBase)WorkTableEnabled,
				(ConfigEntryBase)WorkTableValueMode,
				(ConfigEntryBase)WorkTableMaxItemLines
			});
		}

		public static string DisplayName(ConfigEntryBase entry)
		{
			object[] tags = entry.Description.Tags;
			if (tags != null)
			{
				object[] array = tags;
				for (int i = 0; i < array.Length; i++)
				{
					if (array[i] is MenuInfo menuInfo)
					{
						return menuInfo.Name;
					}
				}
			}
			return entry.Definition.Key;
		}

		private static ConfigEntry<T> Bind<T>(string section, string key, T value, string name, string description)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			return _cfg.Bind<T>(section, key, value, new ConfigDescription(description, (AcceptableValueBase)null, new object[1]
			{
				new MenuInfo(name)
			}));
		}

		private static ConfigEntry<float> Bind(string section, string key, float value, string name, string description, float min, float max)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			return _cfg.Bind<float>(section, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<float>(min, max), new object[1]
			{
				new MenuInfo(name)
			}));
		}

		private static ConfigEntry<int> Bind(string section, string key, int value, string name, string description, int min, int max)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Expected O, but got Unknown
			return _cfg.Bind<int>(section, key, value, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValueRange<int>(min, max), new object[1]
			{
				new MenuInfo(name)
			}));
		}
	}
	[BepInPlugin("no.hakon.storagevision", "Storage Vision", "0.1.2")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PluginGuid = "no.hakon.storagevision";

		public const string PluginName = "Storage Vision";

		public const string PluginVersion = "0.1.2";

		internal static ManualLogSource Log;

		private Harmony _harmony;

		private GameObject _runnerObject;

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			_harmony = new Harmony("no.hakon.storagevision");
			ApplyPatch(typeof(PinpointShelfPatch));
			_runnerObject = new GameObject("StorageVision_Runner");
			Object.DontDestroyOnLoad((Object)(object)_runnerObject);
			((Object)_runnerObject).hideFlags = (HideFlags)61;
			_runnerObject.AddComponent<Runner>();
			_runnerObject.AddComponent<ConfigMenu>();
			Log.LogInfo((object)"Storage Vision 0.1.2 lastet");
		}

		private void ApplyPatch(Type patchClass)
		{
			try
			{
				_harmony.CreateClassProcessor(patchClass).Patch();
			}
			catch (Exception arg)
			{
				Log.LogError((object)$"Failed to apply patch {patchClass.Name} (game update?): {arg}");
			}
		}
	}
	internal sealed class Runner : MonoBehaviour
	{
		private const int MaxLoggedErrors = 10;

		private readonly LookAtService _lookAt = new LookAtService();

		private readonly CenterHud _hud = new CenterHud();

		private readonly GamePanelController _gamePanel = new GamePanelController();

		private readonly Highlighter _highlighter = new Highlighter();

		private readonly OrderTargetFinder _orderTarget = new OrderTargetFinder();

		private readonly List<ILookHandler> _handlers = new List<ILookHandler>
		{
			new StorageShelfHandler(),
			new WorkTableHandler()
		};

		private int _loggedErrors;

		private void LateUpdate()
		{
			try
			{
				Tick();
			}
			catch (Exception e)
			{
				LogError("Runner", e);
				_hud.Hide();
				_highlighter.Clear();
			}
		}

		private void Tick()
		{
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			Transform val = (((Object)(object)GameCanvas.Instance != (Object)null) ? ((Component)GameCanvas.Instance).transform : null);
			_gamePanel.LateUpdate(val);
			LookContext lookContext = (((Object)(object)val != (Object)null) ? _lookAt.Update() : null);
			if (lookContext == null)
			{
				_hud.Hide();
				_highlighter.Clear();
				return;
			}
			lookContext.GamePanelVisible = _gamePanel.IsCenteredAndVisible;
			string text = null;
			GameObject highlightTarget = null;
			foreach (ILookHandler handler in _handlers)
			{
				if (!handler.Enabled)
				{
					continue;
				}
				try
				{
					if (handler.TryHandle(lookContext, out text, out highlightTarget))
					{
						break;
					}
				}
				catch (Exception e)
				{
					LogError(handler.Name + " handler", e);
					text = null;
					highlightTarget = null;
				}
			}
			if (ModConfig.HudEnabled.Value)
			{
				bool isCenteredAndVisible = _gamePanel.IsCenteredAndVisible;
				float topY = (isCenteredAndVisible ? _gamePanel.CenteredBottomY : ModConfig.HudOffsetY.Value);
				_hud.Show(val, text, topY, isCenteredAndVisible ? _gamePanel.PanelRoot.transform : null, _gamePanel.CenteredBounds);
			}
			else
			{
				_hud.Hide();
			}
			_highlighter.Set(ChooseHighlight(lookContext, highlightTarget));
		}

		private GameObject ChooseHighlight(LookContext context, GameObject lookTarget)
		{
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			if (!ModConfig.HighlightEnabled.Value)
			{
				return null;
			}
			switch (ModConfig.HighlightModeEntry.Value)
			{
			case HighlightMode.OrderTarget:
				return _orderTarget.Find(context.LocalPlayer, ((Component)context.Camera).transform.position);
			case HighlightMode.Both:
			{
				GameObject val = _orderTarget.Find(context.LocalPlayer, ((Component)context.Camera).transform.position);
				if (!((Object)(object)val != (Object)null))
				{
					return lookTarget;
				}
				return val;
			}
			default:
				return lookTarget;
			}
		}

		private void OnDestroy()
		{
			_highlighter.Clear();
			_hud.Destroy();
		}

		private void LogError(string where, Exception e)
		{
			if (_loggedErrors < 10)
			{
				_loggedErrors++;
				Plugin.Log.LogError((object)($"{where} failed: {e}" + ((_loggedErrors == 10) ? " (further errors suppressed)" : "")));
			}
		}
	}
}
namespace StorageVision.Patches
{
	[HarmonyPatch(typeof(PinpointShelfFromTray), "GeneratePinpointers")]
	internal static class PinpointShelfPatch
	{
		private static bool Prefix(PinpointShelfFromTray __instance)
		{
			try
			{
				if (!ModConfig.HideOrderArrows.Value)
				{
					return true;
				}
				int currentProductID = __instance.currentProductID;
				__instance.DeactivatePinpointers();
				__instance.currentProductID = currentProductID;
				return false;
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"PinpointShelfPatch failed, falling back to vanilla: {arg}");
				return true;
			}
		}
	}
}
namespace StorageVision.Handlers
{
	internal interface ILookHandler
	{
		string Name { get; }

		bool Enabled { get; }

		bool TryHandle(LookContext context, out string text, out GameObject highlightTarget);
	}
	internal sealed class OrderTargetFinder
	{
		private const float RescanInterval = 0.25f;

		private const int TrayItem = 9;

		private float _nextScan;

		private GameObject _cached;

		private NetworkSpawner _spawner;

		public GameObject Find(PlayerNetwork player, Vector3 viewerPosition)
		{
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || player.equippedItem != 9)
			{
				_cached = null;
				return null;
			}
			OrderPackaging instance = OrderPackaging.Instance;
			PinpointShelfFromTray val = (((Object)(object)instance != (Object)null) ? instance.pinpointerComponent : null);
			if ((Object)(object)val == (Object)null || val.currentProductID < 0)
			{
				_cached = null;
				return null;
			}
			if (Time.unscaledTime < _nextScan && (Object)(object)_cached != (Object)null)
			{
				return _cached;
			}
			_nextScan = Time.unscaledTime + 0.25f;
			_cached = Scan(val.currentProductID, viewerPosition);
			return _cached;
		}

		private GameObject Scan(int productId, Vector3 viewerPosition)
		{
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_spawner == (Object)null)
			{
				if ((Object)(object)GameData.Instance == (Object)null)
				{
					return null;
				}
				_spawner = ((Component)GameData.Instance).GetComponent<NetworkSpawner>();
			}
			if ((Object)(object)_spawner == (Object)null || (Object)(object)_spawner.levelPropsOBJ == (Object)null || _spawner.levelPropsOBJ.transform.childCount < 2)
			{
				return null;
			}
			Transform transform = _spawner.levelPropsOBJ.transform;
			GameObject val = ScanParent(transform.GetChild(1), "BoxContainer", productId, viewerPosition, storage: true);
			if ((Object)(object)val == (Object)null)
			{
				val = ScanParent(transform.GetChild(0), "ProductContainer", productId, viewerPosition, storage: false);
			}
			return val;
		}

		private static GameObject ScanParent(Transform parent, string slotsName, int productId, Vector3 viewer, bool storage)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_00c6: 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_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			GameObject result = null;
			float num = float.MaxValue;
			foreach (Transform item in parent)
			{
				Transform val = item;
				Data_Container component = ((Component)val).GetComponent<Data_Container>();
				if ((Object)(object)component == (Object)null || component.productInfoArray == null)
				{
					continue;
				}
				Transform val2 = val.Find(slotsName);
				if ((Object)(object)val2 == (Object)null)
				{
					continue;
				}
				int[] productInfoArray = component.productInfoArray;
				int num2 = Mathf.Min(productInfoArray.Length / 2, val2.childCount);
				for (int i = 0; i < num2; i++)
				{
					if (productInfoArray[i * 2] != productId || productInfoArray[i * 2 + 1] <= 0)
					{
						continue;
					}
					Transform child = val2.GetChild(i);
					if (child.childCount != 0)
					{
						GameObject val3 = (storage ? ((Component)child.GetChild(0)).gameObject : ((Component)child).gameObject);
						Vector3 val4 = val3.transform.position - viewer;
						float sqrMagnitude = ((Vector3)(ref val4)).sqrMagnitude;
						if (sqrMagnitude < num)
						{
							num = sqrMagnitude;
							result = val3;
						}
					}
				}
			}
			return result;
		}
	}
	internal sealed class StorageShelfHandler : ILookHandler
	{
		private static readonly string Muted = "#B0B0B0";

		private readonly StringBuilder _sb = new StringBuilder(256);

		private Data_Container _lastContainer;

		private int _lastSlot = -1;

		private int _lastProduct = int.MinValue;

		private int _lastAmount = int.MinValue;

		private float _lastShelfPrice = -1f;

		private float _lastMarketPrice = -1f;

		private bool _lastPanelVisible;

		private bool _lastShowPrices;

		private string _lastText;

		public string Name => "Storage";

		public bool Enabled
		{
			get
			{
				if (!ModConfig.StorageEnabled.Value)
				{
					return ModConfig.HighlightEnabled.Value;
				}
				return true;
			}
		}

		public bool TryHandle(LookContext context, out string text, out GameObject highlightTarget)
		{
			text = null;
			highlightTarget = null;
			if (!context.HasInteractableHit)
			{
				return false;
			}
			Transform transform = ((RaycastHit)(ref context.InteractableHit)).transform;
			InteractableContainer component = ((Component)transform).GetComponent<InteractableContainer>();
			if ((Object)(object)component == (Object)null || !component.isStorageShelf || component.isManufacturing || (Object)(object)transform.parent == (Object)null || (Object)(object)transform.parent.parent == (Object)null)
			{
				return false;
			}
			Data_Container component2 = ((Component)transform.parent.parent).GetComponent<Data_Container>();
			if ((Object)(object)component2 == (Object)null || component2.productInfoArray == null)
			{
				return false;
			}
			int siblingIndex = transform.GetSiblingIndex();
			int[] productInfoArray = component2.productInfoArray;
			if (siblingIndex * 2 + 1 >= productInfoArray.Length)
			{
				return false;
			}
			int num = productInfoArray[siblingIndex * 2];
			int num2 = productInfoArray[siblingIndex * 2 + 1];
			if (transform.childCount > 0)
			{
				highlightTarget = ((Component)transform.GetChild(0)).gameObject;
			}
			if (!ModConfig.StorageEnabled.Value)
			{
				return true;
			}
			bool flag = GameInfo.IsValidProduct(num);
			float num3 = (flag ? GameInfo.ShelfPrice(num) : 0f);
			float num4 = (flag ? GameInfo.MarketPrice(num) : 0f);
			bool value = ModConfig.StorageShowPrices.Value;
			if (_lastText != null && (Object)(object)component2 == (Object)(object)_lastContainer && siblingIndex == _lastSlot && num == _lastProduct && num2 == _lastAmount && num3 == _lastShelfPrice && num4 == _lastMarketPrice && context.GamePanelVisible == _lastPanelVisible && value == _lastShowPrices)
			{
				text = _lastText;
				return true;
			}
			_sb.Length = 0;
			if (!flag)
			{
				_sb.Append("<color=").Append(Muted).Append(">Empty storage slot</color>");
			}
			else
			{
				if (!context.GamePanelVisible)
				{
					_sb.Append("<b>").Append(GameInfo.ProductName(num)).Append("</b>");
					string value2 = GameInfo.ProductBrand(num);
					if (!string.IsNullOrEmpty(value2))
					{
						_sb.Append("  <size=80%><color=").Append(Muted).Append('>')
							.Append(value2)
							.Append("</color></size>");
					}
					_sb.Append('\n');
				}
				if (num2 < 0)
				{
					_sb.Append("<color=").Append(Muted).Append(">No box (slot labeled for this product)</color>");
				}
				else
				{
					int num5 = GameInfo.MaxItemsPerBox(num);
					string value3 = ((num2 == 0) ? "#FF7070" : ((num5 > 0 && num2 >= num5) ? "#7CFC7C" : "#FFFFFF"));
					_sb.Append("Box: <b><color=").Append(value3).Append('>')
						.Append(num2)
						.Append("</color></b>");
					if (num5 > 0)
					{
						_sb.Append(" / ").Append(num5);
					}
				}
				if (value)
				{
					_sb.Append("\n<size=85%>Your price ").Append(GameInfo.Price(num3)).Append("  <color=")
						.Append(Muted)
						.Append(">Market ")
						.Append(GameInfo.Price(num4))
						.Append("</color></size>");
				}
			}
			_lastContainer = component2;
			_lastSlot = siblingIndex;
			_lastProduct = num;
			_lastAmount = num2;
			_lastShelfPrice = num3;
			_lastMarketPrice = num4;
			_lastPanelVisible = context.GamePanelVisible;
			_lastShowPrices = value;
			_lastText = _sb.ToString();
			text = _lastText;
			return true;
		}
	}
	internal sealed class WorkTableHandler : ILookHandler
	{
		private const string Muted = "#B0B0B0";

		private const float PayoutMinFactor = 3.25f;

		private const float PayoutMaxFactor = 3.5f;

		private const float BadWeatherFactor = 3f;

		private const int BadWeatherIndex = 4;

		private const int BadWeatherPerk = 43;

		private const float ProximityRadius = 1.3f;

		private const int MaxHierarchyDepth = 8;

		private readonly StringBuilder _sb = new StringBuilder(512);

		private readonly List<int> _orderItems = new List<int>();

		private readonly List<int> _distinct = new List<int>();

		private readonly Dictionary<int, int> _needed = new Dictionary<int, int>();

		private readonly Dictionary<int, int> _onTable = new Dictionary<int, int>();

		private int _lastTable = -1;

		private string _lastOrder;

		private string _lastTableItems;

		private string _lastText;

		private bool _lastActive;

		private int _lastWaiting = -1;

		private int _lastMaxLines = -1;

		private float _lastWeatherFactor = -1f;

		private OrderValueMode _lastMode;

		public string Name => "WorkTable";

		public bool Enabled => ModConfig.WorkTableEnabled.Value;

		public bool TryHandle(LookContext context, out string text, out GameObject highlightTarget)
		{
			text = null;
			highlightTarget = null;
			OrderPackaging instance = OrderPackaging.Instance;
			if ((Object)(object)instance == (Object)null || instance.currentOrderIn == null)
			{
				return false;
			}
			int num = FindLookedAtTable(context, instance);
			if (num < 0 || num >= instance.currentOrderIn.Length)
			{
				return false;
			}
			string text2 = instance.currentOrderIn[num] ?? "";
			string text3 = TableItemsData(instance, num) ?? "";
			bool isOrderDepartmentActivated = instance.isOrderDepartmentActivated;
			int num2 = CountWaitingOrders(instance);
			float num3 = WeatherFactor();
			OrderValueMode value = ModConfig.WorkTableValueMode.Value;
			int value2 = ModConfig.WorkTableMaxItemLines.Value;
			if (_lastText != null && num == _lastTable && text2 == _lastOrder && text3 == _lastTableItems && isOrderDepartmentActivated == _lastActive && num2 == _lastWaiting && num3 == _lastWeatherFactor && value == _lastMode && value2 == _lastMaxLines)
			{
				text = _lastText;
				return true;
			}
			_sb.Length = 0;
			_sb.Append("<b>Packing table #").Append(num + 1).Append("</b>\n");
			if (!isOrderDepartmentActivated)
			{
				_sb.Append("<color=").Append("#B0B0B0").Append(">Online order department is closed</color>\n");
			}
			string[] array = text2.Split('|');
			if (text2.Length == 0 || array.Length < 4)
			{
				_sb.Append("<color=#FF7070>No order assigned</color>");
				_sb.Append("\n<size=85%><color=").Append("#B0B0B0").Append(">Orders waiting: ")
					.Append(num2)
					.Append("</color></size>");
			}
			else
			{
				BuildOrderText(array, text3, value, value2, num3);
			}
			_lastTable = num;
			_lastOrder = text2;
			_lastTableItems = text3;
			_lastActive = isOrderDepartmentActivated;
			_lastWaiting = num2;
			_lastWeatherFactor = num3;
			_lastMode = value;
			_lastMaxLines = value2;
			_lastText = _sb.ToString();
			text = _lastText;
			return true;
		}

		private void BuildOrderText(string[] parts, string tableItems, OrderValueMode mode, int maxLines, float weatherFactor)
		{
			_sb.Append("<color=#7CFC7C>Order #").Append(parts[0]).Append("</color>  ")
				.Append(parts[1])
				.Append('\n');
			ParseIds(parts[3], '_', _orderItems);
			_needed.Clear();
			_distinct.Clear();
			float num = 0f;
			float num2 = 0f;
			foreach (int orderItem in _orderItems)
			{
				if (!_needed.ContainsKey(orderItem))
				{
					_needed[orderItem] = 0;
					_distinct.Add(orderItem);
				}
				_needed[orderItem]++;
				num += GameInfo.MarketPrice(orderItem);
				num2 += GameInfo.ShelfPrice(orderItem);
			}
			_onTable.Clear();
			ParseIds(tableItems, '|', _orderItems);
			int num3 = 0;
			foreach (int orderItem2 in _orderItems)
			{
				_onTable.TryGetValue(orderItem2, out var value);
				_onTable[orderItem2] = value + 1;
			}
			foreach (int item in _distinct)
			{
				if (_onTable.TryGetValue(item, out var value2))
				{
					num3 += Mathf.Min(value2, _needed[item]);
				}
			}
			int num4 = 0;
			foreach (int item2 in _distinct)
			{
				num4 += _needed[item2];
			}
			if (num4 == 0)
			{
				_sb.Append("All items packed");
				return;
			}
			_sb.Append("Items left: <b>").Append(num4).Append("</b>");
			if (num3 > 0)
			{
				_sb.Append("  <color=").Append("#B0B0B0").Append(">(")
					.Append(num3)
					.Append(" on table)</color>");
			}
			_sb.Append('\n');
			if (mode == OrderValueMode.Payout || mode == OrderValueMode.All)
			{
				float value3 = num * 3.25f * weatherFactor;
				float value4 = num * 3.5f * weatherFactor;
				_sb.Append("Value: <b><color=#FFD700>").Append(GameInfo.Price(value3)).Append(" - ")
					.Append(GameInfo.Price(value4))
					.Append("</color></b>");
				if (weatherFactor > 1f)
				{
					_sb.Append(" <size=80%>(bad weather x3)</size>");
				}
				_sb.Append('\n');
			}
			if (mode == OrderValueMode.Market || mode == OrderValueMode.All)
			{
				_sb.Append("Market value: ").Append(GameInfo.Price(num)).Append('\n');
			}
			if (mode == OrderValueMode.ShelfPrice || mode == OrderValueMode.All)
			{
				_sb.Append("At your prices: ").Append(GameInfo.Price(num2)).Append('\n');
			}
			if (maxLines > 0)
			{
				_sb.Append("<size=85%>");
				int num5 = 0;
				foreach (int item3 in _distinct)
				{
					if (num5 >= maxLines)
					{
						break;
					}
					_sb.Append(_needed[item3]).Append("x ").Append(GameInfo.ProductName(item3));
					if (_onTable.TryGetValue(item3, out var value5) && value5 > 0)
					{
						_sb.Append(" <color=#7CFC7C>(").Append(Mathf.Min(value5, _needed[item3])).Append(" on table)</color>");
					}
					_sb.Append('\n');
					num5++;
				}
				if (_distinct.Count > num5)
				{
					_sb.Append("<color=").Append("#B0B0B0").Append(">+")
						.Append(_distinct.Count - num5)
						.Append(" more products</color>\n");
				}
				_sb.Append("</size>");
			}
			if (_sb.Length > 0 && _sb[_sb.Length - 1] == '\n')
			{
				_sb.Length--;
			}
		}

		private static void ParseIds(string data, char separator, List<int> result)
		{
			result.Clear();
			if (string.IsNullOrEmpty(data))
			{
				return;
			}
			string[] array = data.Split(separator);
			for (int i = 0; i < array.Length; i++)
			{
				if (int.TryParse(array[i], out var result2) && GameInfo.IsValidProduct(result2))
				{
					result.Add(result2);
				}
			}
		}

		private static string TableItemsData(OrderPackaging packaging, int table)
		{
			return table switch
			{
				0 => packaging.itemsData0, 
				1 => packaging.itemsData1, 
				2 => packaging.itemsData2, 
				3 => packaging.itemsData3, 
				_ => "", 
			};
		}

		private static int CountWaitingOrders(OrderPackaging packaging)
		{
			int num = 0;
			if (packaging.ordersData != null)
			{
				string[] ordersData = packaging.ordersData;
				for (int i = 0; i < ordersData.Length; i++)
				{
					if (!string.IsNullOrEmpty(ordersData[i]))
					{
						num++;
					}
				}
			}
			return num;
		}

		private static float WeatherFactor()
		{
			GameData instance = GameData.Instance;
			if ((Object)(object)instance == (Object)null || instance.weatherIndex < 4)
			{
				return 1f;
			}
			bool flag = (Object)(object)NPC_Manager.Instance != (Object)null && NPC_Manager.Instance.orderingExtraCrashOnBadWeather;
			if (!flag)
			{
				UpgradesManager component = ((Component)instance).GetComponent<UpgradesManager>();
				if (component != null && component.extraUpgrades != null && component.extraUpgrades.Length > 43)
				{
					flag = component.extraUpgrades[43];
				}
			}
			if (!flag)
			{
				return 1f;
			}
			return 3f;
		}

		private static int FindLookedAtTable(LookContext context, OrderPackaging packaging)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			Transform transform = ((Component)context.LocalPlayer).transform;
			for (int i = 0; i < context.AllHitCount; i++)
			{
				RaycastHit val = context.AllHits[i];
				if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !((RaycastHit)(ref val)).transform.IsChildOf(transform))
				{
					int num = TableFromHierarchy(((RaycastHit)(ref val)).transform, packaging);
					if (num >= 0)
					{
						return num;
					}
					if (!((RaycastHit)(ref val)).collider.isTrigger)
					{
						return TableFromProximity(((RaycastHit)(ref val)).point, packaging);
					}
				}
			}
			return -1;
		}

		private static int TableFromHierarchy(Transform t, OrderPackaging packaging)
		{
			Transform val = (((Object)(object)packaging.interactableCamerasParentOBJ != (Object)null) ? packaging.interactableCamerasParentOBJ.transform : null);
			Transform val2 = (((Object)(object)packaging.boxContainersParentOBJ != (Object)null) ? packaging.boxContainersParentOBJ.transform : null);
			Transform val3 = (((Object)(object)packaging.itemSpawnPivotsParentOBJ != (Object)null) ? packaging.itemSpawnPivotsParentOBJ.transform : null);
			Transform val4 = (((Object)(object)packaging.tablesCanvasesParentOBJ != (Object)null) ? packaging.tablesCanvasesParentOBJ.transform : null);
			int num = 0;
			while ((Object)(object)t != (Object)null && num < 8)
			{
				if ((Object)(object)((Component)t).GetComponent<OrderPackagingReference>() != (Object)null)
				{
					return t.GetSiblingIndex();
				}
				Transform parent = t.parent;
				if ((Object)(object)parent != (Object)null && ((Object)(object)parent == (Object)(object)val || (Object)(object)parent == (Object)(object)val2 || (Object)(object)parent == (Object)(object)val3 || (Object)(object)parent == (Object)(object)val4))
				{
					return t.GetSiblingIndex();
				}
				num++;
				t = t.parent;
			}
			return -1;
		}

		private static int TableFromProximity(Vector3 point, OrderPackaging packaging)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)packaging.itemSpawnPivotsParentOBJ == (Object)null)
			{
				return -1;
			}
			Transform transform = packaging.itemSpawnPivotsParentOBJ.transform;
			int result = -1;
			float num = 1.6899998f;
			for (int i = 0; i < transform.childCount; i++)
			{
				Vector3 val = transform.GetChild(i).position - point;
				val.y = 0f;
				float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
				if (sqrMagnitude < num)
				{
					num = sqrMagnitude;
					result = i;
				}
			}
			return result;
		}
	}
}
namespace StorageVision.Core
{
	internal sealed class CenterHud
	{
		private Transform _canvasRoot;

		private GameObject _root;

		private RectTransform _rootRect;

		private Image _background;

		private VerticalLayoutGroup _layout;

		private TextMeshProUGUI _text;

		private string _currentText;

		private GameObject _backdrop;

		private RectTransform _backdropRect;

		private Image _backdropImage;

		public void Show(Transform gameCanvas, string text, float topY, Transform gamePanel, Rect gamePanelBounds)
		{
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: 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)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				bool flag = !string.IsNullOrEmpty(text);
				if (!flag && (Object)(object)gamePanel == (Object)null)
				{
					Hide();
				}
				else
				{
					if (!EnsureCreated(gameCanvas))
					{
						return;
					}
					float value = ModConfig.HudBackgroundOpacity.Value;
					bool flag2 = (Object)(object)gamePanel != (Object)null && value > 0.001f;
					if (flag)
					{
						if (text != _currentText)
						{
							((TMP_Text)_text).text = text;
							_currentText = text;
						}
						ApplyStyle(flag2 ? 0f : value);
						ApplyPadding(flag2 ? 0f : ModConfig.HudBackgroundPadding.Value);
						Vector2 val = default(Vector2);
						((Vector2)(ref val))..ctor(ModConfig.HudOffsetX.Value, topY);
						if (_rootRect.anchoredPosition != val)
						{
							_rootRect.anchoredPosition = val;
						}
						SetActive(_root, active: true);
						if (_root.transform.GetSiblingIndex() != _root.transform.parent.childCount - 1)
						{
							_root.transform.SetAsLastSibling();
						}
					}
					else
					{
						SetActive(_root, active: false);
					}
					if (flag2)
					{
						Rect val2 = gamePanelBounds;
						if (flag)
						{
							val2 = Union(val2, TextBounds());
						}
						PlaceBackdrop(val2, value, gamePanel);
					}
					else
					{
						SetActive(_backdrop, active: false);
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"CenterHud.Show failed: {arg}");
				Destroy();
			}
		}

		public void Hide()
		{
			SetActive(_root, active: false);
			SetActive(_backdrop, active: false);
		}

		public void Destroy()
		{
			if ((Object)(object)_root != (Object)null)
			{
				Object.Destroy((Object)(object)_root);
			}
			if ((Object)(object)_backdrop != (Object)null)
			{
				Object.Destroy((Object)(object)_backdrop);
			}
			_root = null;
			_backdrop = null;
			_currentText = null;
		}

		private Rect TextBounds()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			Rect rect = _rootRect.rect;
			Vector2 size = ((Rect)(ref rect)).size;
			Vector2 anchoredPosition = _rootRect.anchoredPosition;
			return new Rect(anchoredPosition.x - size.x * 0.5f, anchoredPosition.y - size.y, size.x, size.y);
		}

		private void ApplyPadding(float padding)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Expected O, but got Unknown
			int num = Mathf.RoundToInt(padding);
			RectOffset padding2 = ((LayoutGroup)_layout).padding;
			if (padding2.left != num || padding2.top != num)
			{
				((LayoutGroup)_layout).padding = new RectOffset(num, num, num, num);
			}
		}

		private void PlaceBackdrop(Rect area, float opacity, Transform gamePanel)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			float value = ModConfig.HudBackgroundPadding.Value;
			area = Rect.MinMaxRect(((Rect)(ref area)).xMin - value, ((Rect)(ref area)).yMin - value, ((Rect)(ref area)).xMax + value, ((Rect)(ref area)).yMax + value);
			if (_backdropRect.anchoredPosition != ((Rect)(ref area)).center)
			{
				_backdropRect.anchoredPosition = ((Rect)(ref area)).center;
			}
			if (_backdropRect.sizeDelta != ((Rect)(ref area)).size)
			{
				_backdropRect.sizeDelta = ((Rect)(ref area)).size;
			}
			Color val = default(Color);
			((Color)(ref val))..ctor(0f, 0f, 0f, opacity);
			if (((Graphic)_backdropImage).color != val)
			{
				((Graphic)_backdropImage).color = val;
			}
			if ((Object)(object)gamePanel.parent == (Object)(object)_backdrop.transform.parent)
			{
				int siblingIndex = gamePanel.GetSiblingIndex();
				if (_backdrop.transform.GetSiblingIndex() > siblingIndex)
				{
					_backdrop.transform.SetSiblingIndex(siblingIndex);
				}
			}
			SetActive(_backdrop, active: true);
		}

		private bool EnsureCreated(Transform gameCanvas)
		{
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Expected O, but got Unknown
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Expected O, but got Unknown
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0130: Expected O, but got Unknown
			//IL_019c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Expected O, but got Unknown
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0268: Expected O, but got Unknown
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Expected O, but got Unknown
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e5: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_root != (Object)null && (Object)(object)_backdrop != (Object)null && (Object)(object)_canvasRoot == (Object)(object)gameCanvas)
			{
				return true;
			}
			Destroy();
			if ((Object)(object)gameCanvas == (Object)null)
			{
				return false;
			}
			_canvasRoot = gameCanvas;
			_root = new GameObject("StorageVision_CenterHud", new Type[1] { typeof(RectTransform) });
			_root.layer = ((Component)gameCanvas).gameObject.layer;
			_rootRect = (RectTransform)_root.transform;
			((Transform)_rootRect).SetParent(gameCanvas, false);
			_rootRect.anchorMin = new Vector2(0.5f, 0.5f);
			_rootRect.anchorMax = new Vector2(0.5f, 0.5f);
			_rootRect.pivot = new Vector2(0.5f, 1f);
			_background = _root.AddComponent<Image>();
			((Graphic)_background).raycastTarget = false;
			_layout = _root.AddComponent<VerticalLayoutGroup>();
			((LayoutGroup)_layout).padding = new RectOffset(0, 0, 0, 0);
			((LayoutGroup)_layout).childAlignment = (TextAnchor)1;
			((HorizontalOrVerticalLayoutGroup)_layout).childControlWidth = true;
			((HorizontalOrVerticalLayoutGroup)_layout).childControlHeight = true;
			((HorizontalOrVerticalLayoutGroup)_layout).childForceExpandWidth = false;
			((HorizontalOrVerticalLayoutGroup)_layout).childForceExpandHeight = false;
			ContentSizeFitter obj = _root.AddComponent<ContentSizeFitter>();
			obj.horizontalFit = (FitMode)2;
			obj.verticalFit = (FitMode)2;
			GameObject val = new GameObject("Text", new Type[1] { typeof(RectTransform) });
			val.layer = _root.layer;
			val.transform.SetParent((Transform)(object)_rootRect, false);
			_text = val.AddComponent<TextMeshProUGUI>();
			((Graphic)_text).raycastTarget = false;
			((TMP_Text)_text).richText = true;
			((TMP_Text)_text).alignment = (TextAlignmentOptions)514;
			((TMP_Text)_text).textWrappingMode = (TextWrappingModes)0;
			Transform obj2 = gameCanvas.Find("ProductShow/Container/ProductName");
			TMP_Text val2 = ((obj2 != null) ? ((Component)obj2).GetComponent<TMP_Text>() : null);
			if ((Object)(object)val2 != (Object)null && (Object)(object)val2.font != (Object)null)
			{
				((TMP_Text)_text).font = val2.font;
			}
			_backdrop = new GameObject("StorageVision_Backdrop", new Type[1] { typeof(RectTransform) });
			_backdrop.layer = ((Component)gameCanvas).gameObject.layer;
			_backdropRect = (RectTransform)_backdrop.transform;
			((Transform)_backdropRect).SetParent(gameCanvas, false);
			_backdropRect.anchorMin = new Vector2(0.5f, 0.5f);
			_backdropRect.anchorMax = new Vector2(0.5f, 0.5f);
			_backdropRect.pivot = new Vector2(0.5f, 0.5f);
			_backdropImage = _backdrop.AddComponent<Image>();
			((Graphic)_backdropImage).raycastTarget = false;
			_currentText = null;
			_root.SetActive(false);
			_backdrop.SetActive(false);
			return true;
		}

		private void ApplyStyle(float backgroundOpacity)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: 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_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: 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)
			float value = ModConfig.HudFontSize.Value;
			if (!Mathf.Approximately(((TMP_Text)_text).fontSize, value))
			{
				((TMP_Text)_text).fontSize = value;
			}
			Color value2 = ModConfig.HudTextColor.Value;
			if (((Graphic)_text).color != value2)
			{
				((Graphic)_text).color = value2;
			}
			Color val = default(Color);
			((Color)(ref val))..ctor(0f, 0f, 0f, backgroundOpacity);
			if (((Graphic)_background).color != val)
			{
				((Graphic)_background).color = val;
			}
			bool flag = val.a > 0.001f;
			if (((Behaviour)_background).enabled != flag)
			{
				((Behaviour)_background).enabled = flag;
			}
		}

		private static Rect Union(Rect a, Rect b)
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			return Rect.MinMaxRect(Mathf.Min(((Rect)(ref a)).xMin, ((Rect)(ref b)).xMin), Mathf.Min(((Rect)(ref a)).yMin, ((Rect)(ref b)).yMin), Mathf.Max(((Rect)(ref a)).xMax, ((Rect)(ref b)).xMax), Mathf.Max(((Rect)(ref a)).yMax, ((Rect)(ref b)).yMax));
		}

		private static void SetActive(GameObject go, bool active)
		{
			if ((Object)(object)go != (Object)null && go.activeSelf != active)
			{
				go.SetActive(active);
			}
		}
	}
	internal sealed class ConfigMenu : MonoBehaviour
	{
		private const int WindowId = 21334;

		private const float OffsetRange = 800f;

		private const float WindowWidth = 580f;

		private const float WindowHeight = 820f;

		private const float ScrollHeight = 720f;

		private const float ContentWidth = 532f;

		private const float LabelWidth = 190f;

		private const float ValueWidth = 46f;

		private const float ControlWidth = 334f;

		private static readonly KeyValuePair<string, Color>[] Swatches = new KeyValuePair<string, Color>[7]
		{
			new KeyValuePair<string, Color>("Green", Color.green),
			new KeyValuePair<string, Color>("Yellow", Color.yellow),
			new KeyValuePair<string, Color>("Cyan", Color.cyan),
			new KeyValuePair<string, Color>("Magenta", Color.magenta),
			new KeyValuePair<string, Color>("Red", Color.red),
			new KeyValuePair<string, Color>("Orange", new Color(1f, 0.55f, 0f)),
			new KeyValuePair<string, Color>("White", Color.white)
		};

		private Rect _window = new Rect(40f, 40f, 580f, 820f);

		private Vector2 _scroll;

		private readonly StringBuilder _sb = new StringBuilder();

		private CursorLockMode _prevLockMode;

		private bool _prevCursorVisible;

		private FirstPersonController _blockedController;

		private readonly List<ControllerMap> _mapBuffer = new List<ControllerMap>();

		private readonly List<ControllerMap> _disabledMaps = new List<ControllerMap>();

		private bool _prevSaveOnSet = true;

		private Texture2D _windowTexture;

		private GUIStyle _windowStyle;

		private GUIStyle _headerStyle;

		private GUIStyle _descriptionStyle;

		private GUIStyle _labelStyle;

		public static bool IsOpen { get; private set; }

		private void Update()
		{
			//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_004d: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				KeyboardShortcut value = ModConfig.MenuKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					if (IsOpen)
					{
						Close();
					}
					else
					{
						Open();
					}
				}
				else if (IsOpen && UnityInput.Current.GetKeyDown((KeyCode)27))
				{
					Close();
				}
				if (IsOpen)
				{
					if ((int)Cursor.lockState != 0)
					{
						Cursor.lockState = (CursorLockMode)0;
					}
					if (!Cursor.visible)
					{
						Cursor.visible = true;
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"ConfigMenu.Update failed: {arg}");
				if (IsOpen)
				{
					Close();
				}
			}
		}

		private void Open()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			IsOpen = true;
			_prevLockMode = Cursor.lockState;
			_prevCursorVisible = Cursor.visible;
			FirstPersonController instance = FirstPersonController.Instance;
			if ((Object)(object)instance != (Object)null && instance.allowPlayerInput)
			{
				instance.allowPlayerInput = false;
				_blockedController = instance;
			}
			_disabledMaps.Clear();
			try
			{
				if (ReInput.isReady)
				{
					Player player = ReInput.players.GetPlayer(0);
					_mapBuffer.Clear();
					player.controllers.maps.GetAllMaps(_mapBuffer);
					foreach (ControllerMap item in _mapBuffer)
					{
						if (item != null && item.enabled)
						{
							item.enabled = false;
							_disabledMaps.Add(item);
						}
					}
				}
			}
			catch (Exception ex)
			{
				Plugin.Log.LogWarning((object)("Could not pause game input for the menu: " + ex.Message));
			}
			_prevSaveOnSet = ModConfig.File.SaveOnConfigSet;
			ModConfig.File.SaveOnConfigSet = false;
		}

		private void Close()
		{
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			IsOpen = false;
			foreach (ControllerMap disabledMap in _disabledMaps)
			{
				try
				{
					if (disabledMap != null)
					{
						disabledMap.enabled = true;
					}
				}
				catch (Exception ex)
				{
					Plugin.Log.LogWarning((object)("Could not restore an input map: " + ex.Message));
				}
			}
			_disabledMaps.Clear();
			if ((Object)(object)_blockedController != (Object)null && !_blockedController.allowPlayerInput)
			{
				_blockedController.allowPlayerInput = true;
			}
			_blockedController = null;
			Cursor.lockState = _prevLockMode;
			Cursor.visible = _prevCursorVisible;
			try
			{
				ModConfig.File.Save();
			}
			catch (Exception ex2)
			{
				Plugin.Log.LogError((object)("Could not save config: " + ex2.Message));
			}
			ModConfig.File.SaveOnConfigSet = _prevSaveOnSet;
		}

		private void OnDestroy()
		{
			if (IsOpen)
			{
				Close();
			}
			if ((Object)(object)_windowTexture != (Object)null)
			{
				Object.Destroy((Object)(object)_windowTexture);
			}
		}

		private void OnGUI()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: 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_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Expected O, but got Unknown
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			if (!IsOpen)
			{
				return;
			}
			try
			{
				EnsureStyles();
				float num = Mathf.Clamp((float)Screen.height / 1080f, 0.75f, 2.5f);
				Matrix4x4 matrix = GUI.matrix;
				GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(num, num, 1f));
				_window = GUILayout.Window(21334, _window, new WindowFunction(DrawWindow), "Storage Vision  -  " + ((object)ModConfig.MenuKey.Value/*cast due to .constrained prefix*/).ToString() + " / Esc to close", _windowStyle, Array.Empty<GUILayoutOption>());
				GUI.matrix = matrix;
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"ConfigMenu.OnGUI failed: {arg}");
				Close();
			}
		}

		private void EnsureStyles()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			//IL_0032: 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_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_007c: Expected O, but got Unknown
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00ff: 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_0119: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Expected O, but got Unknown
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0146: Unknown result type (might be due to invalid IL or missing references)
			//IL_014b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0152: Unknown result type (might be due to invalid IL or missing references)
			//IL_015f: Expected O, but got Unknown
			//IL_0179: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Expected O, but got Unknown
			if (_windowStyle == null)
			{
				_windowTexture = new Texture2D(1, 1);
				_windowTexture.SetPixel(0, 0, new Color(0.08f, 0.08f, 0.1f, 0.96f));
				_windowTexture.Apply();
				((Object)_windowTexture).hideFlags = (HideFlags)61;
				_windowStyle = new GUIStyle(GUI.skin.window)
				{
					padding = new RectOffset(12, 12, 28, 12)
				};
				_windowStyle.normal.background = _windowTexture;
				_windowStyle.onNormal.background = _windowTexture;
				_windowStyle.fontSize = 15;
				_windowStyle.fontStyle = (FontStyle)1;
				_headerStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 15,
					fontStyle = (FontStyle)1
				};
				_headerStyle.normal.textColor = new Color(0.45f, 1f, 0.45f);
				_labelStyle = new GUIStyle(GUI.skin.label)
				{
					fontSize = 14
				};
				_labelStyle.normal.textColor = Color.white;
				_descriptionStyle = new GUIStyle(GUI.skin.label)
				{
					wordWrap = true,
					fontSize = 12
				};
				_descriptionStyle.normal.textColor = new Color(0.68f, 0.68f, 0.7f);
				_descriptionStyle.margin = new RectOffset(4, 4, 0, 6);
			}
		}

		private void DrawWindow(int id)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			_scroll = GUILayout.BeginScrollView(_scroll, false, true, GUIStyle.none, GUI.skin.verticalScrollbar, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(720f) });
			GUILayout.BeginVertical((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(532f) });
			string text = null;
			foreach (ConfigEntryBase menuEntry in ModConfig.MenuEntries)
			{
				if (menuEntry.Definition.Section != text)
				{
					text = menuEntry.Definition.Section;
					GUILayout.Space((text == ModConfig.MenuEntries[0].Definition.Section) ? 0f : 10f);
					GUILayout.Label(StripNumber(text), _headerStyle, Array.Empty<GUILayoutOption>());
				}
				try
				{
					DrawEntry(menuEntry);
				}
				catch (Exception ex)
				{
					GUILayout.Label(menuEntry.Definition.Key + ": " + ex.Message, Array.Empty<GUILayoutOption>());
				}
			}
			GUILayout.EndVertical();
			GUILayout.EndScrollView();
			GUILayout.Space(6f);
			GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
			if (GUILayout.Button("Reset to defaults", Array.Empty<GUILayoutOption>()))
			{
				foreach (ConfigEntryBase menuEntry2 in ModConfig.MenuEntries)
				{
					menuEntry2.BoxedValue = menuEntry2.DefaultValue;
				}
			}
			if (GUILayout.Button("Close", Array.Empty<GUILayoutOption>()))
			{
				Close();
			}
			GUILayout.EndHorizontal();
			GUI.DragWindow(new Rect(0f, 0f, 10000f, 24f));
		}

		private void DrawEntry(ConfigEntryBase entry)
		{
			//IL_030f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0314: Unknown result type (might be due to invalid IL or missing references)
			//IL_0316: Unknown result type (might be due to invalid IL or missing references)
			//IL_031b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0334: Unknown result type (might be due to invalid IL or missing references)
			//IL_0338: Unknown result type (might be due to invalid IL or missing references)
			//IL_0344: Unknown result type (might be due to invalid IL or missing references)
			//IL_03b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0363: Unknown result type (might be due to invalid IL or missing references)
			//IL_038d: Expected O, but got Unknown
			//IL_0392: Unknown result type (might be due to invalid IL or missing references)
			string text = ModConfig.DisplayName(entry);
			Type settingType = entry.SettingType;
			if (settingType == typeof(bool))
			{
				bool flag = (bool)entry.BoxedValue;
				bool flag2 = GUILayout.Toggle(flag, " " + text, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(532f) });
				if (flag2 != flag)
				{
					entry.BoxedValue = flag2;
				}
				DrawDescription(entry);
				return;
			}
			GUILayout.BeginHorizontal((GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(532f) });
			GUILayout.Label(text, _labelStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(190f) });
			if (settingType == typeof(float))
			{
				float num = (float)entry.BoxedValue;
				float num2 = -800f;
				float num3 = 800f;
				if (entry.Description.AcceptableValues is AcceptableValueRange<float> val)
				{
					num2 = val.MinValue;
					num3 = val.MaxValue;
				}
				float num4 = GUILayout.HorizontalSlider(num, num2, num3, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(288f) });
				num4 = ((num3 - num2 > 20f) ? Mathf.Round(num4) : (Mathf.Round(num4 * 100f) / 100f));
				GUILayout.Label(num4.ToString((num3 - num2 > 20f) ? "0" : "0.00"), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(46f) });
				if (!Mathf.Approximately(num4, num))
				{
					entry.BoxedValue = num4;
				}
			}
			else if (settingType == typeof(int))
			{
				int num5 = (int)entry.BoxedValue;
				int num6 = 0;
				int num7 = 100;
				if (entry.Description.AcceptableValues is AcceptableValueRange<int> val2)
				{
					num6 = val2.MinValue;
					num7 = val2.MaxValue;
				}
				int num8 = Mathf.RoundToInt(GUILayout.HorizontalSlider((float)num5, (float)num6, (float)num7, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(288f) }));
				GUILayout.Label(num8.ToString(), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(46f) });
				if (num8 != num5)
				{
					entry.BoxedValue = num8;
				}
			}
			else if (settingType.IsEnum)
			{
				Array values = Enum.GetValues(settingType);
				string[] array = new string[values.Length];
				int num9 = 0;
				for (int i = 0; i < values.Length; i++)
				{
					array[i] = Nicify(values.GetValue(i).ToString());
					if (object.Equals(values.GetValue(i), entry.BoxedValue))
					{
						num9 = i;
					}
				}
				int num10 = GUILayout.Toolbar(num9, array, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(334f) });
				if (num10 != num9)
				{
					entry.BoxedValue = values.GetValue(num10);
				}
			}
			else if (settingType == typeof(Color))
			{
				Color a = (Color)entry.BoxedValue;
				Color backgroundColor = GUI.backgroundColor;
				KeyValuePair<string, Color>[] swatches = Swatches;
				for (int j = 0; j < swatches.Length; j++)
				{
					KeyValuePair<string, Color> keyValuePair = swatches[j];
					bool num11 = ApproximatelyEqual(a, keyValuePair.Value);
					GUI.backgroundColor = keyValuePair.Value;
					if (GUILayout.Button(new GUIContent(num11 ? "X" : "", keyValuePair.Key), (GUILayoutOption[])(object)new GUILayoutOption[2]
					{
						GUILayout.Width(30f),
						GUILayout.Height(20f)
					}))
					{
						entry.BoxedValue = keyValuePair.Value;
					}
				}
				GUI.backgroundColor = backgroundColor;
			}
			else
			{
				GUILayout.Label(entry.GetSerializedValue(), Array.Empty<GUILayoutOption>());
			}
			GUILayout.EndHorizontal();
			DrawDescription(entry);
		}

		private void DrawDescription(ConfigEntryBase entry)
		{
			ConfigDescription description = entry.Description;
			string text = ((description != null) ? description.Description : null);
			if (!string.IsNullOrEmpty(text))
			{
				GUILayout.Label(text, _descriptionStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(532f) });
			}
		}

		private static bool ApproximatelyEqual(Color a, Color b)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			if (Mathf.Abs(a.r - b.r) < 0.02f && Mathf.Abs(a.g - b.g) < 0.02f)
			{
				return Mathf.Abs(a.b - b.b) < 0.02f;
			}
			return false;
		}

		private static string StripNumber(string section)
		{
			int num = section.IndexOf(". ", StringComparison.Ordinal);
			if (num < 0 || num > 2)
			{
				return section;
			}
			return section.Substring(num + 2);
		}

		private string Nicify(string name)
		{
			_sb.Length = 0;
			for (int i = 0; i < name.Length; i++)
			{
				char c = name[i];
				if (i > 0 && char.IsUpper(c) && !char.IsUpper(name[i - 1]))
				{
					_sb.Append(' ');
				}
				_sb.Append(c);
			}
			return _sb.ToString();
		}
	}
	internal static class GameInfo
	{
		public static bool IsValidProduct(int productId)
		{
			ProductListing instance = ProductListing.Instance;
			if ((Object)(object)instance != (Object)null && instance.productsData != null && productId >= 0)
			{
				return productId < instance.productsData.Length;
			}
			return false;
		}

		public static string ProductName(int productId)
		{
			LocalizationManager instance = LocalizationManager.instance;
			if (!((Object)(object)instance != (Object)null))
			{
				return "Product " + productId;
			}
			return instance.GetLocalizationString("product" + productId);
		}

		public static string ProductBrand(int productId)
		{
			if (!IsValidProduct(productId))
			{
				return "";
			}
			return ProductListing.Instance.productsData[productId].productBrand;
		}

		public static float MarketPrice(int productId)
		{
			if (!IsValidProduct(productId))
			{
				return 0f;
			}
			ProductListing instance = ProductListing.Instance;
			ProductData val = instance.productsData[productId];
			float num = 1f;
			if (instance.tierInflation != null && val.productTier >= 0 && val.productTier < instance.tierInflation.Length)
			{
				num = instance.tierInflation[val.productTier];
			}
			return val.basePricePerUnit * num;
		}

		public static float ShelfPrice(int productId)
		{
			ProductListing instance = ProductListing.Instance;
			if ((Object)(object)instance == (Object)null || instance.productPlayerPricing == null || productId < 0 || productId >= instance.productPlayerPricing.Length)
			{
				return 0f;
			}
			return instance.productPlayerPricing[productId];
		}

		public static int MaxItemsPerBox(int productId)
		{
			if (!IsValidProduct(productId))
			{
				return 0;
			}
			return ProductListing.Instance.productsData[productId].maxItemsPerBox;
		}

		public static string Price(float value)
		{
			ProductListing instance = ProductListing.Instance;
			if ((Object)(object)instance != (Object)null)
			{
				return instance.ConvertFloatToTextPrice(value);
			}
			return "$" + (Mathf.Round(value * 100f) / 100f).ToString("0.00");
		}

		public static string Hex(Color c)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			return ColorUtility.ToHtmlStringRGB(c);
		}
	}
	internal sealed class GamePanelController
	{
		private sealed class ScaledText
		{
			public TMP_Text Text;

			public float FontSize;

			public float FontSizeMin;

			public float FontSizeMax;

			public TextWrappingModes Wrapping;

			public TextOverflowModes Overflow;

			public float AppliedScale = 1f;
		}

		private const float Spacing = 6f;

		private Transform _canvasRoot;

		private GameObject _panelRoot;

		private RectTransform _panelRect;

		private CanvasGroup _canvasGroup;

		private bool _loggedLayout;

		private readonly List<ScaledText> _texts = new List<ScaledText>();

		private readonly List<Graphic> _graphics = new List<Graphic>();

		private readonly Vector3[] _corners = (Vector3[])(object)new Vector3[4];

		private Vector2 _origAnchorMin;

		private Vector2 _origAnchorMax;

		private Vector2 _origPivot;

		private Vector2 _origPosition;

		private Vector3 _origScale;

		private float _origAlpha = 1f;

		public bool IsCenteredAndVisible { get; private set; }

		public float CenteredBottomY { get; private set; }

		public Rect CenteredBounds { get; private set; }

		public GameObject PanelRoot => _panelRoot;

		public void LateUpdate(Transform gameCanvas)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
			IsCenteredAndVisible = false;
			try
			{
				if ((Object)(object)gameCanvas == (Object)null || (((Object)(object)_panelRoot == (Object)null || (Object)(object)_canvasRoot != (Object)(object)gameCanvas) && !Find(gameCanvas)))
				{
					return;
				}
				switch (ModConfig.HudEnabled.Value ? ModConfig.OriginalPanel.Value : OriginalPanelMode.Keep)
				{
				case OriginalPanelMode.Hide:
					RestoreLayout();
					ScaleTexts(1f);
					SetAlpha(0f);
					break;
				case OriginalPanelMode.MoveToCenter:
					SetAlpha(_origAlpha);
					ApplyCenterLayout();
					ScaleTexts(ModConfig.ProductTextScale.Value);
					if (_panelRoot.activeInHierarchy)
					{
						IsCenteredAndVisible = true;
						CenteredBounds = MeasureBounds(gameCanvas);
						Rect centeredBounds = CenteredBounds;
						CenteredBottomY = ((Rect)(ref centeredBounds)).yMin - 6f;
					}
					break;
				default:
					RestoreLayout();
					ScaleTexts(1f);
					SetAlpha(_origAlpha);
					break;
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"GamePanelController failed, leaving panel as is: {arg}");
				_panelRoot = null;
			}
		}

		private bool Find(Transform gameCanvas)
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: 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_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: 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_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			_canvasRoot = gameCanvas;
			Transform val = gameCanvas.Find("ProductShow");
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			_panelRoot = ((Component)val).gameObject;
			RectTransform val2 = (RectTransform)(object)((val is RectTransform) ? val : null);
			RectTransform val3 = val2;
			if ((Object)(object)val2 != (Object)null && val2.anchorMin != val2.anchorMax)
			{
				Transform obj = val.Find("Container");
				RectTransform val4 = (RectTransform)(object)((obj is RectTransform) ? obj : null);
				if ((Object)(object)val4 != (Object)null)
				{
					val3 = val4;
				}
			}
			if ((Object)(object)val3 == (Object)null)
			{
				_panelRoot = null;
				return false;
			}
			_panelRect = val3;
			_origAnchorMin = val3.anchorMin;
			_origAnchorMax = val3.anchorMax;
			_origPivot = val3.pivot;
			_origPosition = val3.anchoredPosition;
			_origScale = ((Transform)val3).localScale;
			_canvasGroup = ((Component)val).GetComponent<CanvasGroup>();
			if ((Object)(object)_canvasGroup == (Object)null)
			{
				_canvasGroup = ((Component)val).gameObject.AddComponent<CanvasGroup>();
				_canvasGroup.interactable = false;
				_canvasGroup.blocksRaycasts = false;
				_origAlpha = 1f;
			}
			else
			{
				_origAlpha = _canvasGroup.alpha;
			}
			_texts.Clear();
			AddScaledText(val, "Container/ProductName");
			AddScaledText(val, "Container/ProductBrand");
			if (!_loggedLayout)
			{
				_loggedLayout = true;
				ManualLogSource log = Plugin.Log;
				string text = $"Found game product panel '{((Object)val3).name}': anchors {_origAnchorMin}-{_origAnchorMax}, ";
				object[] obj2 = new object[4] { _origPivot, _origPosition, null, null };
				Rect rect = val3.rect;
				obj2[2] = ((Rect)(ref rect)).size;
				obj2[3] = _texts.Count;
				log.LogInfo((object)(text + string.Format("pivot {0}, pos {1}, size {2}, scalable texts {3}", obj2)));
			}
			return true;
		}

		private void AddScaledText(Transform root, string path)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			Transform obj = root.Find(path);
			TMP_Text val = ((obj != null) ? ((Component)obj).GetComponent<TMP_Text>() : null);
			if (!((Object)(object)val == (Object)null))
			{
				_texts.Add(new ScaledText
				{
					Text = val,
					FontSize = val.fontSize,
					FontSizeMin = val.fontSizeMin,
					FontSizeMax = val.fontSizeMax,
					Wrapping = val.textWrappingMode,
					Overflow = val.overflowMode
				});
			}
		}

		private void ScaleTexts(float scale)
		{
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			foreach (ScaledText text in _texts)
			{
				if (!((Object)(object)text.Text == (Object)null) && !Mathf.Approximately(text.AppliedScale, scale))
				{
					text.Text.fontSize = text.FontSize * scale;
					text.Text.fontSizeMin = text.FontSizeMin * scale;
					text.Text.fontSizeMax = text.FontSizeMax * scale;
					bool flag = Mathf.Approximately(scale, 1f);
					text.Text.textWrappingMode = (TextWrappingModes)(flag ? ((int)text.Wrapping) : 0);
					text.Text.overflowMode = (TextOverflowModes)(flag ? ((int)text.Overflow) : 0);
					text.AppliedScale = scale;
				}
			}
		}

		private Rect MeasureBounds(Transform gameCanvas)
		{
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: 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_00fa: 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_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			float xMin = float.MaxValue;
			float yMin = float.MaxValue;
			float xMax = float.MinValue;
			float yMax = float.MinValue;
			bool flag = false;
			_graphics.Clear();
			_panelRoot.GetComponentsInChildren<Graphic>(false, _graphics);
			foreach (Graphic graphic in _graphics)
			{
				if (!((Behaviour)graphic).enabled || graphic.color.a <= 0.01f)
				{
					continue;
				}
				RectTransform rectTransform = graphic.rectTransform;
				TMP_Text val = (TMP_Text)(object)((graphic is TMP_Text) ? graphic : null);
				if (val != null)
				{
					if (string.IsNullOrEmpty(val.text))
					{
						continue;
					}
					Bounds textBounds = val.textBounds;
					if (((Bounds)(ref textBounds)).size.x <= 0f || ((Bounds)(ref textBounds)).size.y <= 0f)
					{
						continue;
					}
					_corners[0] = ((Transform)rectTransform).TransformPoint(new Vector3(((Bounds)(ref textBounds)).min.x, ((Bounds)(ref textBounds)).min.y));
					_corners[1] = ((Transform)rectTransform).TransformPoint(new Vector3(((Bounds)(ref textBounds)).max.x, ((Bounds)(ref textBounds)).max.y));
					Encapsulate(gameCanvas, 2, ref xMin, ref yMin, ref xMax, ref yMax);
				}
				else
				{
					rectTransform.GetWorldCorners(_corners);
					Encapsulate(gameCanvas, 4, ref xMin, ref yMin, ref xMax, ref yMax);
				}
				flag = true;
			}
			if (!flag)
			{
				Bounds val2 = RectTransformUtility.CalculateRelativeRectTransformBounds(gameCanvas, _panelRoot.transform);
				xMin = ((Bounds)(ref val2)).min.x;
				yMin = ((Bounds)(ref val2)).min.y;
				xMax = ((Bounds)(ref val2)).max.x;
				yMax = ((Bounds)(ref val2)).max.y;
			}
			RectTransform val3 = (RectTransform)(object)((gameCanvas is RectTransform) ? gameCanvas : null);
			Vector2 val4;
			if (val3 == null)
			{
				val4 = Vector2.zero;
			}
			else
			{
				Rect rect = val3.rect;
				val4 = ((Rect)(ref rect)).center;
			}
			Vector2 val5 = val4;
			return Rect.MinMaxRect(xMin - val5.x, yMin - val5.y, xMax - val5.x, yMax - val5.y);
		}

		private void Encapsulate(Transform gameCanvas, int count, ref float xMin, ref float yMin, ref float xMax, ref float yMax)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 0; i < count; i++)
			{
				Vector3 val = gameCanvas.InverseTransformPoint(_corners[i]);
				if (val.x < xMin)
				{
					xMin = val.x;
				}
				if (val.y < yMin)
				{
					yMin = val.y;
				}
				if (val.x > xMax)
				{
					xMax = val.x;
				}
				if (val.y > yMax)
				{
					yMax = val.y;
				}
			}
		}

		private void ApplyCenterLayout()
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0.5f, 0.5f);
			Vector2 pivot = default(Vector2);
			((Vector2)(ref pivot))..ctor(0.5f, 1f);
			Vector2 position = default(Vector2);
			((Vector2)(ref position))..ctor(ModConfig.HudOffsetX.Value, ModConfig.HudOffsetY.Value);
			float value = ModConfig.OriginalPanelScale.Value;
			Vector3 scale = default(Vector3);
			((Vector3)(ref scale))..ctor(_origScale.x * value, _origScale.y * value, _origScale.z);
			SetLayout(val, val, pivot, position, scale);
		}

		private void RestoreLayout()
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			SetLayout(_origAnchorMin, _origAnchorMax, _origPivot, _origPosition, _origScale);
		}

		private void SetLayout(Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 position, Vector3 scale)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: 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_0068: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			if (_panelRect.anchorMin != anchorMin)
			{
				_panelRect.anchorMin = anchorMin;
			}
			if (_panelRect.anchorMax != anchorMax)
			{
				_panelRect.anchorMax = anchorMax;
			}
			if (_panelRect.pivot != pivot)
			{
				_panelRect.pivot = pivot;
			}
			if (_panelRect.anchoredPosition != position)
			{
				_panelRect.anchoredPosition = position;
			}
			if (((Transform)_panelRect).localScale != scale)
			{
				((Transform)_panelRect).localScale = scale;
			}
		}

		private void SetAlpha(float alpha)
		{
			if ((Object)(object)_canvasGroup != (Object)null && !Mathf.Approximately(_canvasGroup.alpha, alpha))
			{
				_canvasGroup.alpha = alpha;
			}
		}
	}
	internal sealed class Highlighter
	{
		private struct SavedSettings
		{
			public bool Enabled;

			public bool Highlighted;

			public float Outline;

			public Color OutlineColor;

			public float OutlineWidth;

			public Visibility OutlineVisibility;

			public float Glow;

			public float Overlay;

			public float InnerGlow;
		}

		private GameObject _target;

		private HighlightEffect _effect;

		private bool _addedByUs;

		private SavedSettings _saved;

		private Color _appliedColor;

		private float _appliedWidth;

		private bool _appliedOnTop;

		public GameObject Current => _target;

		public void Set(GameObject target)
		{
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)_target == (Object)null && _target != null)
				{
					Forget();
				}
				if ((Object)(object)target == (Object)(object)_target)
				{
					if ((Object)(object)_effect != (Object)null)
					{
						ApplyStyleIfChanged(force: false);
					}
					return;
				}
				Clear();
				if (!((Object)(object)target == (Object)null))
				{
					_target = target;
					_effect = target.GetComponent<HighlightEffect>();
					if ((Object)(object)_effect != (Object)null)
					{
						_addedByUs = false;
						_saved = new SavedSettings
						{
							Enabled = ((Behaviour)_effect).enabled,
							Highlighted = _effect.highlighted,
							Outline = _effect.outline,
							OutlineColor = _effect.outlineColor,
							OutlineWidth = _effect.outlineWidth,
							OutlineVisibility = _effect.outlineVisibility,
							Glow = _effect.glow,
							Overlay = _effect.overlay,
							InnerGlow = _effect.innerGlow
						};
						_effect.glow = 0f;
						_effect.overlay = 0f;
						_effect.innerGlow = 0f;
					}
					else
					{
						_addedByUs = true;
						_effect = target.AddComponent<HighlightEffect>();
						_effect.outlineQuality = (QualityLevel)1;
					}
					((Behaviour)_effect).enabled = true;
					_effect.outline = 1f;
					ApplyStyleIfChanged(force: true);
					_effect.highlighted = true;
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Highlighter.Set failed: {arg}");
				Clear();
			}
		}

		public void Clear()
		{
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0083: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)_effect != (Object)null)
				{
					if (_addedByUs)
					{
						_effect.highlighted = false;
						Object.Destroy((Object)(object)_effect);
					}
					else
					{
						_effect.outline = _saved.Outline;
						_effect.outlineColor = _saved.OutlineColor;
						_effect.outlineWidth = _saved.OutlineWidth;
						_effect.outlineVisibility = _saved.OutlineVisibility;
						_effect.glow = _saved.Glow;
						_effect.overlay = _saved.Overlay;
						_effect.innerGlow = _saved.InnerGlow;
						_effect.highlighted = _saved.Highlighted;
						((Behaviour)_effect).enabled = _saved.Enabled;
						_effect.UpdateMaterialProperties();
					}
				}
			}
			catch (Exception arg)
			{
				Plugin.Log.LogError((object)$"Highlighter.Clear failed: {arg}");
			}
			Forget();
		}

		private void Forget()
		{
			_target = null;
			_effect = null;
			_addedByUs = false;
		}

		private void ApplyStyleIfChanged(bool force)
		{
			//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_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_006f: 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_0081: Unknown result type (might be due to invalid IL or missing references)
			Color value = ModConfig.HighlightColor.Value;
			float value2 = ModConfig.HighlightWidth.Value;
			bool value3 = ModConfig.HighlightAlwaysOnTop.Value;
			if (force || !(value == _appliedColor) || !Mathf.Approximately(value2, _appliedWidth) || value3 != _appliedOnTop)
			{
				_effect.outlineColor = value;
				_effect.outlineWidth = value2;
				_effect.outlineVisibility = (Visibility)(value3 ? 1 : 0);
				_effect.UpdateMaterialProperties();
				_appliedColor = value;
				_appliedWidth = value2;
				_appliedOnTop = value3;
			}
		}
	}
	internal sealed class LookContext
	{
		public bool HasInteractableHit;

		public RaycastHit InteractableHit;

		public readonly RaycastHit[] AllHits = (RaycastHit[])(object)new RaycastHit[16];

		public int AllHitCount;

		public Camera Camera;

		public PlayerNetwork LocalPlayer;

		public bool GamePanelVisible;
	}
	internal sealed class LookAtService
	{
		public const float MaxDistance = 4f;

		private readonly LookContext _context = new LookContext();

		private PlayerNetwork _cachedPlayer;

		private FirstPersonController _cachedController;

		public LookContext Update()
		{
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
			FirstPersonController instance = FirstPersonController.Instance;
			if ((Object)(object)instance == (Object)null)
			{
				_cachedPlayer = null;
				return null;
			}
			if ((Object)(object)instance != (Object)(object)_cachedController || (Object)(object)_cachedPlayer == (Object)null)
			{
				_cachedController = instance;
				_cachedPlayer = ((Component)instance).GetComponent<PlayerNetwork>();
			}
			Camera main = Camera.main;
			if ((Object)(object)_cachedPlayer == (Object)null || (Object)(object)main == (Object)null || (!instance.allowPlayerInput && !ConfigMenu.IsOpen))
			{
				return null;
			}
			Transform transform = ((Component)main).transform;
			Vector3 position = transform.position;
			Vector3 forward = transform.forward;
			_context.Camera = main;
			_context.LocalPlayer = _cachedPlayer;
			_context.HasInteractableHit = Physics.Raycast(position, forward, ref _context.InteractableHit, 4f, LayerMask.op_Implicit(_cachedPlayer.interactableMask));
			int num = Physics.RaycastNonAlloc(position, forward, _context.AllHits, 4f, -5, (QueryTriggerInteraction)2);
			SortByDistance(_context.AllHits, num);
			_context.AllHitCount = num;
			return _context;
		}

		private static void SortByDistance(RaycastHit[] hits, int count)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			for (int i = 1; i < count; i++)
			{
				RaycastHit val = hits[i];
				int num = i - 1;
				while (num >= 0 && ((RaycastHit)(ref hits[num])).distance > ((RaycastHit)(ref val)).distance)
				{
					hits[num + 1] = hits[num];
					num--;
				}
				hits[num + 1] = val;
			}
		}
	}
}