Decompiled source of Nivalis Dish Queue v1.0.0

NivalisDishQueue.dll

Decompiled 17 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Nivalis;
using Nivalis.GhostSystem;
using Nivalis.GhostSystem.Ai;
using Nivalis.GhostSystem.CustomerLoop;
using TMPro;
using UnityEngine;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace NivalisDishQueue
{
	public enum HudStyleOption
	{
		Game,
		Classic
	}
	public enum PickupMode
	{
		Stack,
		Off
	}
	[BepInPlugin("com.saiko.nivalisdishqueue", "Nivalis Dish Queue", "1.0.0")]
	public class DishQueuePlugin : BasePlugin
	{
		public const string Guid = "com.saiko.nivalisdishqueue";

		public const string Name = "Nivalis Dish Queue";

		public const string Version = "1.0.0";

		public static ManualLogSource Logger;

		public static ConfigEntry<PickupMode> Mode;

		public static ConfigEntry<int> MaxExtraDishes;

		public static ConfigEntry<float> NextDishDelaySeconds;

		public static ConfigEntry<bool> FastTrayAnimations;

		public static ConfigEntry<bool> ShowHud;

		public static ConfigEntry<HudStyleOption> HudStyle;

		public static ConfigEntry<float> HudScale;

		public static ConfigEntry<bool> VerboseLog;

		public override void Load()
		{
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0122: Unknown result type (might be due to invalid IL or missing references)
			//IL_0128: Expected O, but got Unknown
			//IL_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Expected O, but got Unknown
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			Logger = ((BasePlugin)this).Log;
			Mode = ((BasePlugin)this).Config.Bind<PickupMode>("General", "Mode", PickupMode.Stack, "Stack = carry several dishes (default). Off = the mod does nothing and the game behaves as normal.");
			MaxExtraDishes = ((BasePlugin)this).Config.Bind<int>("Stack", "MaxExtraDishes", 3, "How many dishes you can stack on your tray besides the one in your hands (3 = carry 4 in total).");
			NextDishDelaySeconds = ((BasePlugin)this).Config.Bind<float>("Stack", "NextDishDelaySeconds", 0.6f, "Pause after serving or dropping a dish before the next stacked dish moves into your hands, in seconds. 0 = instant.");
			FastTrayAnimations = ((BasePlugin)this).Config.Bind<bool>("Stack", "FastTrayAnimations", false, "true = skip the tray animations (taking a dish into your hands, putting one down, serving, dropping plates) so they finish instantly. false = the game's normal animations.");
			ShowHud = ((BasePlugin)this).Config.Bind<bool>("Display", "ShowHud", true, "Show the \"On Your Tray\" panel listing the dish in your hands and the stacked dishes, and the short message at the bottom of the screen when a dish can't be picked up (tray full, wrong kind of dish...).");
			HudStyle = ((BasePlugin)this).Config.Bind<HudStyleOption>("Display", "HudStyle", HudStyleOption.Game, "Game = the panel uses the game's own font and quest-list look. Classic = a simple rounded panel.");
			HudScale = ((BasePlugin)this).Config.Bind<float>("Display", "HudScale", 1f, "Size of the panel: 1 = normal, 1.2 = 20% bigger, 0.8 = 20% smaller.");
			VerboseLog = ((BasePlugin)this).Config.Bind<bool>("Debug", "VerboseLog", false, "Write every stacking step to BepInEx\\LogOutput.log (useful when reporting a bug).");
			ClassInjector.RegisterTypeInIl2Cpp<QueueRunner>();
			GameObject val = new GameObject("NivalisDishQueueRunner");
			Object.DontDestroyOnLoad((Object)val);
			((Object)val).hideFlags = (HideFlags)61;
			val.AddComponent<QueueRunner>();
			Patches.ApplyAll(new Harmony("com.saiko.nivalisdishqueue"));
			ManualLogSource log = ((BasePlugin)this).Log;
			bool flag = default(bool);
			BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(31, 4, ref flag);
			if (flag)
			{
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("Nivalis Dish Queue");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>("1.0.0");
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" loaded. Mode=");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<PickupMode>(Mode.Value);
				((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" MaxExtraDishes=");
				((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(MaxExtraDishes.Value);
			}
			log.LogInfo(val2);
		}
	}
	internal static class GameHud
	{
		private class TextStyle
		{
			public TMP_FontAsset Font;

			public Material Mat;
		}

		private class Marker
		{
			public Image Main;

			public Image Inner;

			public void SetColor(Color c, bool filled)
			{
				//IL_0006: 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_0023: Unknown result type (might be due to invalid IL or missing references)
				((Graphic)Main).color = c;
				if ((Object)(object)Inner != (Object)null)
				{
					((Graphic)Inner).color = (filled ? c : PanelBg);
				}
			}
		}

		private class Row
		{
			public GameObject Go;

			public Marker Marker;

			public TextMeshProUGUI Text;
		}

		private static Color Gold = Hex(220, 176, 117);

		private static Color Blue = Hex(97, 157, 228);

		private static Color Step = Hex(170, 162, 159);

		private static readonly Color Dim = new Color(0.45f, 0.43f, 0.42f, 1f);

		private static readonly Color PanelBg = new Color(0.05f, 0.055f, 0.065f, 0.94f);

		private static readonly Color Border = new Color(0.62f, 0.54f, 0.38f, 0.95f);

		private const float Width = 390f;

		private const float PadTop = 24f;

		private const float PadBottom = 22f;

		private const float TitleH = 50f;

		private const float StepH = 35f;

		private const float FontSize = 20f;

		private const float BadgeNumberLift = 3.5f;

		private const float FrameScale = 1.6f;

		private static TextStyle titleStyle;

		private static TextStyle activeStyle;

		private static TextStyle stepStyle;

		private static Sprite frameSprite;

		private static Sprite checkSprite;

		private static Sprite hexSprite;

		private static bool failed;

		private static float nextSearch;

		private static GameObject root;

		private static CanvasGroup panelGroup;

		private static CanvasGroup toastGroup;

		private static RectTransform panel;

		private static RectTransform toast;

		private static Image frame;

		private static Image[] borders;

		private static TextMeshProUGUI countText;

		private static TextMeshProUGUI badgeText;

		private static TextMeshProUGUI toastText;

		private static Image badge;

		private static Row held;

		private static readonly List<Row> rows = new List<Row>();

		private static int builtRows = -1;

		private static float lastTime;

		public static bool Active
		{
			get
			{
				if (!failed && (Object)(object)root != (Object)null)
				{
					return DishQueuePlugin.HudStyle.Value == HudStyleOption.Game;
				}
				return false;
			}
		}

		public static void Tick(QueueRunner r)
		{
			if (failed || DishQueuePlugin.HudStyle.Value != HudStyleOption.Game)
			{
				if ((Object)(object)root != (Object)null)
				{
					root.SetActive(false);
				}
				return;
			}
			try
			{
				if ((Object)(object)root == (Object)null)
				{
					if (!FindGameStyle())
					{
						return;
					}
					Build();
				}
				if (!root.activeSelf)
				{
					root.SetActive(true);
				}
				Refresh(r);
			}
			catch (Exception ex)
			{
				failed = true;
				DishQueuePlugin.Logger.LogError((object)("game-styled panel failed, using the classic panel instead: " + ex));
				try
				{
					if ((Object)(object)root != (Object)null)
					{
						Object.Destroy((Object)(object)root);
					}
				}
				catch
				{
				}
				root = null;
			}
		}

		private static bool FindGameStyle()
		{
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: 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_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: Unknown result type (might be due to invalid IL or missing references)
			//IL_013a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			if (Time.unscaledTime < nextSearch)
			{
				return false;
			}
			nextSearch = Time.unscaledTime + 2f;
			Il2CppReferenceArray<Object> val = Object.FindObjectsOfType(Il2CppType.Of<TextMeshProUGUI>());
			for (int i = 0; i < ((Il2CppArrayBase<Object>)(object)val).Length; i++)
			{
				TextMeshProUGUI val2 = ((((Il2CppArrayBase<Object>)(object)val)[i] != (Object)null) ? ((Il2CppObjectBase)((Il2CppArrayBase<Object>)(object)val)[i]).TryCast<TextMeshProUGUI>() : null);
				if ((Object)(object)val2 == (Object)null || !((Behaviour)val2).isActiveAndEnabled || (Object)(object)((TMP_Text)val2).font == (Object)null || !UnderNamed(((TMP_Text)val2).transform, "HUD_RightColumnStack"))
				{
					continue;
				}
				TextStyle textStyle = new TextStyle
				{
					Font = ((TMP_Text)val2).font,
					Mat = ((TMP_Text)val2).fontSharedMaterial
				};
				Color color = ((Graphic)val2).color;
				if (((Object)val2).name == "QuestTitle")
				{
					if (color.b > color.r + 0.2f)
					{
						if (activeStyle == null)
						{
							activeStyle = textStyle;
							Blue = Opaque(color);
						}
					}
					else if (titleStyle == null)
					{
						titleStyle = textStyle;
						Gold = Opaque(color);
					}
				}
				else if (((Object)val2).name == "QuestObjective" && stepStyle == null)
				{
					stepStyle = textStyle;
					Step = Opaque(color);
				}
			}
			if (titleStyle == null || stepStyle == null)
			{
				return false;
			}
			if (activeStyle == null)
			{
				activeStyle = titleStyle;
			}
			Il2CppReferenceArray<Object> val3 = Object.FindObjectsOfType(Il2CppType.Of<Image>());
			for (int j = 0; j < ((Il2CppArrayBase<Object>)(object)val3).Length; j++)
			{
				Image val4 = ((((Il2CppArrayBase<Object>)(object)val3)[j] != (Object)null) ? ((Il2CppObjectBase)((Il2CppArrayBase<Object>)(object)val3)[j]).TryCast<Image>() : null);
				if (!((Object)(object)val4 == (Object)null) && !((Object)(object)val4.sprite == (Object)null) && UnderNamed(((Component)val4).transform, "P_Journal_HUD"))
				{
					if ((Object)(object)frameSprite == (Object)null && ((Object)val4).name == "OuterWrapper")
					{
						frameSprite = val4.sprite;
					}
					else if ((Object)(object)checkSprite == (Object)null && ((Object)val4).name == "CheckBox")
					{
						checkSprite = val4.sprite;
					}
					else if ((Object)(object)hexSprite == (Object)null && ((Object)val4).name == "Image" && (Object)(object)((Component)val4).transform.parent != (Object)null && ((Object)((Component)val4).transform.parent).name == "MainLine")
					{
						hexSprite = val4.sprite;
					}
				}
			}
			DishQueuePlugin.Logger.LogInfo((object)("panel styled from the quest tracker: title font '" + ((Object)titleStyle.Font).name + "', step font '" + ((Object)stepStyle.Font).name + "', frame=" + (((Object)(object)frameSprite != (Object)null) ? ((Object)frameSprite).name : "drawn") + ", diamond=" + (((Object)(object)checkSprite != (Object)null) ? ((Object)checkSprite).name : "drawn") + ", badge=" + (((Object)(object)hexSprite != (Object)null) ? ((Object)hexSprite).name : "drawn")));
			return true;
		}

		private static bool UnderNamed(Transform t, string name)
		{
			Transform val = t;
			while ((Object)(object)val != (Object)null)
			{
				if (((Object)val).name == name)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private static void Build()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Expected O, but got Unknown
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_00b6: 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_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: 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_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0212: Unknown result type (might be due to invalid IL or missing references)
			//IL_0221: Unknown result type (might be due to invalid IL or missing references)
			//IL_0226: Unknown result type (might be due to invalid IL or missing references)
			//IL_0235: Unknown result type (might be due to invalid IL or missing references)
			//IL_0251: Unknown result type (might be due to invalid IL or missing references)
			//IL_0260: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0274: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_02fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_030b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_033f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0376: Unknown result type (might be due to invalid IL or missing references)
			//IL_037c: Unknown result type (might be due to invalid IL or missing references)
			//IL_037d: Unknown result type (might be due to invalid IL or missing references)
			//IL_037e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0384: Unknown result type (might be due to invalid IL or missing references)
			//IL_0395: Unknown result type (might be due to invalid IL or missing references)
			//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0420: Unknown result type (might be due to invalid IL or missing references)
			//IL_0462: Unknown result type (might be due to invalid IL or missing references)
			//IL_04e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_0502: Unknown result type (might be due to invalid IL or missing references)
			//IL_051b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0534: Unknown result type (might be due to invalid IL or missing references)
			//IL_056b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0596: Unknown result type (might be due to invalid IL or missing references)
			//IL_05a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_05ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0622: Unknown result type (might be due to invalid IL or missing references)
			//IL_0627: Unknown result type (might be due to invalid IL or missing references)
			//IL_062a: Unknown result type (might be due to invalid IL or missing references)
			//IL_062f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0632: Unknown result type (might be due to invalid IL or missing references)
			//IL_0637: Unknown result type (might be due to invalid IL or missing references)
			//IL_0639: Unknown result type (might be due to invalid IL or missing references)
			//IL_063e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0647: Unknown result type (might be due to invalid IL or missing references)
			//IL_0657: Unknown result type (might be due to invalid IL or missing references)
			//IL_065f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0667: Unknown result type (might be due to invalid IL or missing references)
			//IL_066e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0696: Unknown result type (might be due to invalid IL or missing references)
			root = new GameObject("NivalisDishQueueHud");
			Object.DontDestroyOnLoad((Object)(object)root);
			Canvas obj = root.AddComponent<Canvas>();
			obj.renderMode = (RenderMode)0;
			obj.sortingOrder = 5;
			CanvasScaler obj2 = root.AddComponent<CanvasScaler>();
			obj2.uiScaleMode = (ScaleMode)1;
			obj2.referenceResolution = new Vector2(1920f, 1080f);
			obj2.screenMatchMode = (ScreenMatchMode)0;
			obj2.matchWidthOrHeight = 0.9f;
			panel = NewRect("Panel", root.transform);
			RectTransform obj3 = panel;
			RectTransform obj4 = panel;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 1f);
			obj4.anchorMax = val;
			obj3.anchorMin = val;
			panel.pivot = new Vector2(0f, 1f);
			panel.anchoredPosition = new Vector2(18f, -360f);
			panelGroup = ((Component)panel).gameObject.AddComponent<CanvasGroup>();
			panelGroup.alpha = 0f;
			if ((Object)(object)frameSprite != (Object)null)
			{
				frame = NewImage("Frame", (Transform)(object)panel, Color.white);
				frame.sprite = frameSprite;
				frame.type = (Type)1;
				frame.pixelsPerUnitMultiplier = 1.6f;
				Stretch(((Graphic)frame).rectTransform);
			}
			else
			{
				Stretch(((Graphic)NewImage("Bg", (Transform)(object)panel, PanelBg)).rectTransform);
				borders = (Image[])(object)new Image[4]
				{
					Edge("BorderTop", new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, -2f), Vector2.zero),
					Edge("BorderBottom", new Vector2(0f, 0f), new Vector2(1f, 0f), Vector2.zero, new Vector2(0f, 2f)),
					Edge("BorderLeft", new Vector2(0f, 0f), new Vector2(0f, 1f), Vector2.zero, new Vector2(3f, 0f)),
					Edge("BorderRight", new Vector2(1f, 0f), new Vector2(1f, 1f), new Vector2(-2f, 0f), Vector2.zero)
				};
			}
			float num = -24f;
			if ((Object)(object)hexSprite != (Object)null)
			{
				badge = NewImage("Badge", (Transform)(object)panel, Gold);
				badge.sprite = hexSprite;
				badge.preserveAspect = true;
				Place(((Graphic)badge).rectTransform, 20f, num, 45f, 50f);
			}
			else
			{
				NewMarker((Transform)(object)panel, new Vector2(42f, num - 25f), 28f).SetColor(Gold, filled: false);
			}
			if ((Object)(object)badge != (Object)null)
			{
				badgeText = NewText("Number", ((Component)badge).transform, "0", 17.5f, Gold, (TextAlignmentOptions)544, titleStyle);
				RectTransform rectTransform = ((TMP_Text)badgeText).rectTransform;
				Vector2 val2 = default(Vector2);
				((Vector2)(ref val2))..ctor(0.5f, 0.5f);
				rectTransform.pivot = val2;
				val = (rectTransform.anchorMin = (rectTransform.anchorMax = val2));
				rectTransform.anchoredPosition = new Vector2(0f, 3.5f);
				rectTransform.sizeDelta = new Vector2(22f, 21f);
				((TMP_Text)badgeText).overflowMode = (TextOverflowModes)0;
			}
			else
			{
				badgeText = NewText("BadgeText", (Transform)(object)panel, "0", 15f, Gold, (TextAlignmentOptions)544, titleStyle);
				Place(((TMP_Text)badgeText).rectTransform, 20f, num, 45f, 50f);
			}
			Place(((TMP_Text)NewText("Title", (Transform)(object)panel, "On Your Tray", 20f, Gold, (TextAlignmentOptions)4097, titleStyle)).rectTransform, 74f, num, 190f, 50f);
			countText = NewText("Count", (Transform)(object)panel, "", 18f, Step, (TextAlignmentOptions)4100, stepStyle);
			Place(((TMP_Text)countText).rectTransform, 254f, num, 110f, 50f);
			held = NewRow((Transform)(object)panel, -74f, activeStyle);
			toast = NewRect("Toast", root.transform);
			RectTransform obj5 = toast;
			RectTransform obj6 = toast;
			((Vector2)(ref val))..ctor(0.5f, 0f);
			obj6.anchorMax = val;
			obj5.anchorMin = val;
			toast.pivot = new Vector2(0.5f, 0f);
			toast.anchoredPosition = new Vector2(0f, 150f);
			toast.sizeDelta = new Vector2(400f, 42f);
			toastGroup = ((Component)toast).gameObject.AddComponent<CanvasGroup>();
			toastGroup.alpha = 0f;
			Stretch(((Graphic)NewImage("Bg", (Transform)(object)toast, PanelBg)).rectTransform);
			(string, Vector2, Vector2, Vector2, Vector2)[] array = new(string, Vector2, Vector2, Vector2, Vector2)[2]
			{
				("Top", new Vector2(0f, 1f), new Vector2(1f, 1f), new Vector2(0f, -2f), Vector2.zero),
				("Bottom", new Vector2(0f, 0f), new Vector2(1f, 0f), Vector2.zero, new Vector2(0f, 2f))
			};
			for (int i = 0; i < array.Length; i++)
			{
				(string, Vector2, Vector2, Vector2, Vector2) tuple = array[i];
				string item = tuple.Item1;
				Vector2 item2 = tuple.Item2;
				Vector2 item3 = tuple.Item3;
				Vector2 item4 = tuple.Item4;
				Vector2 item5 = tuple.Item5;
				RectTransform rectTransform2 = ((Graphic)NewImage(item, (Transform)(object)toast, Border)).rectTransform;
				rectTransform2.anchorMin = item2;
				rectTransform2.anchorMax = item3;
				rectTransform2.offsetMin = item4;
				rectTransform2.offsetMax = item5;
			}
			toastText = NewText("Text", (Transform)(object)toast, "", 20f, Step, (TextAlignmentOptions)514, stepStyle);
			Stretch(((TMP_Text)toastText).rectTransform);
		}

		private static Row NewRow(Transform parent, float y, TextStyle style)
		{
			//IL_001f: 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_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			RectTransform val = NewRect("Row", parent);
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0f, 1f);
			val.anchorMax = val2;
			val.anchorMin = val2;
			val.pivot = new Vector2(0f, 1f);
			val.anchoredPosition = new Vector2(0f, y);
			val.sizeDelta = new Vector2(390f, 35f);
			Row obj = new Row
			{
				Go = ((Component)val).gameObject,
				Marker = NewMarker((Transform)(object)val, new Vector2(62f, -17.5f), ((Object)(object)checkSprite != (Object)null) ? 30f : 15f),
				Text = NewText("Text", (Transform)(object)val, "", 20f, Step, (TextAlignmentOptions)4097, style)
			};
			Place(((TMP_Text)obj.Text).rectTransform, 88f, 0f, 276f, 35f);
			return obj;
		}

		private static void BuildRows(int count)
		{
			foreach (Row row in rows)
			{
				Object.Destroy((Object)(object)row.Go);
			}
			rows.Clear();
			for (int i = 0; i < count; i++)
			{
				rows.Add(NewRow((Transform)(object)panel, -74f - 35f * (float)(i + 1), stepStyle));
			}
			builtRows = count;
		}

		private static void Refresh(QueueRunner r)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0201: Unknown result type (might be due to invalid IL or missing references)
			//IL_0206: Unknown result type (might be due to invalid IL or missing references)
			//IL_0207: Unknown result type (might be due to invalid IL or missing references)
			//IL_020e: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0232: Unknown result type (might be due to invalid IL or missing references)
			//IL_0239: Unknown result type (might be due to invalid IL or missing references)
			//IL_0322: Unknown result type (might be due to invalid IL or missing references)
			//IL_0336: Unknown result type (might be due to invalid IL or missing references)
			//IL_02e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0413: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_03d0: Unknown result type (might be due to invalid IL or missing references)
			float unscaledTime = Time.unscaledTime;
			float num = Mathf.Clamp(unscaledTime - lastTime, 0f, 0.1f);
			lastTime = unscaledTime;
			int num2 = Mathf.Clamp(DishQueuePlugin.MaxExtraDishes.Value, 1, 6);
			if (num2 != builtRows)
			{
				BuildRows(num2);
			}
			float num3 = Mathf.Clamp(DishQueuePlugin.HudScale.Value, 0.5f, 2.5f);
			RectTransform obj = panel;
			RectTransform obj2 = toast;
			Vector3 localScale = default(Vector3);
			((Vector3)(ref localScale))..ctor(num3, num3, 1f);
			((Transform)obj2).localScale = localScale;
			((Transform)obj).localScale = localScale;
			bool num4 = Time.timeScale <= 0f;
			bool flag = DishQueuePlugin.Mode.Value == PickupMode.Stack;
			bool flag2 = !num4 && flag && DishQueuePlugin.ShowHud.Value && (r.HeldLabel != null || r.Stacked.Count > 0);
			panelGroup.alpha = Mathf.MoveTowards(panelGroup.alpha, flag2 ? 1f : 0f, num * 6f);
			bool flag3 = !num4 && DishQueuePlugin.ShowHud.Value && unscaledTime < r.ToastUntil && !string.IsNullOrEmpty(r.Toast);
			toastGroup.alpha = Mathf.MoveTowards(toastGroup.alpha, flag3 ? 1f : 0f, num * 5f);
			if (flag3 && ((TMP_Text)toastText).text != r.Toast)
			{
				((TMP_Text)toastText).text = r.Toast;
				toast.sizeDelta = new Vector2(Mathf.Max(260f, ((TMP_Text)toastText).preferredWidth + 56f), 42f);
			}
			if (panelGroup.alpha <= 0.001f)
			{
				return;
			}
			float num5 = Mathf.Clamp01((r.FlashUntil - unscaledTime) / 1.2f);
			if ((Object)(object)badge != (Object)null)
			{
				Image obj3 = badge;
				Color color = (((Graphic)badgeText).color = Color.Lerp(Gold, Blue, num5));
				((Graphic)obj3).color = color;
			}
			if (borders != null)
			{
				Image[] array = borders;
				for (int i = 0; i < array.Length; i++)
				{
					((Graphic)array[i]).color = Color.Lerp(Border, Blue, num5);
				}
			}
			bool flag4 = QueueRunner.IsCleanupJob(MealView.CurrentPlayerTask);
			int num6 = r.Stacked.Count + ((r.HeldLabel != null) ? 1 : 0);
			SetText(badgeText, num6.ToString());
			SetText(countText, num6 + " / " + (num2 + 1) + (flag4 ? " plates" : " dishes"));
			if (r.HeldLabel != null)
			{
				SetText(held.Text, r.HeldLabel);
				((Graphic)held.Text).color = Blue;
				held.Marker.SetColor(Blue, filled: true);
			}
			else
			{
				SetText(held.Text, "Hands free - next dish coming");
				((Graphic)held.Text).color = Dim;
				held.Marker.SetColor(Dim, filled: false);
			}
			int num7 = Mathf.Min(r.Stacked.Count, rows.Count);
			for (int j = 0; j < rows.Count; j++)
			{
				Row row = rows[j];
				bool flag5 = j < num7;
				if (row.Go.activeSelf != flag5)
				{
					row.Go.SetActive(flag5);
				}
				if (flag5)
				{
					SetText(row.Text, r.Stacked[j].Label);
					((Graphic)row.Text).color = Step;
					row.Marker.SetColor(Step, filled: false);
				}
			}
			panel.sizeDelta = new Vector2(390f, 74f + 35f * (float)(1 + num7) + 22f);
		}

		private static void SetText(TextMeshProUGUI t, string s)
		{
			if (((TMP_Text)t).text != s)
			{
				((TMP_Text)t).text = s;
			}
		}

		private static RectTransform NewRect(string name, Transform parent)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			RectTransform obj = new GameObject(name)
			{
				layer = 5
			}.AddComponent<RectTransform>();
			((Transform)obj).SetParent(parent, false);
			return obj;
		}

		private static Image NewImage(string name, Transform parent, Color color)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			Image obj = ((Component)NewRect(name, parent)).gameObject.AddComponent<Image>();
			((Graphic)obj).color = color;
			((Graphic)obj).raycastTarget = false;
			return obj;
		}

		private static TextMeshProUGUI NewText(string name, Transform parent, string text, float size, Color color, TextAlignmentOptions align, TextStyle role)
		{
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			TextMeshProUGUI val = ((Component)NewRect(name, parent)).gameObject.AddComponent<TextMeshProUGUI>();
			((TMP_Text)val).font = role.Font;
			if ((Object)(object)role.Mat != (Object)null)
			{
				((TMP_Text)val).fontSharedMaterial = role.Mat;
			}
			((TMP_Text)val).fontSize = size;
			((TMP_Text)val).fontStyle = (FontStyles)0;
			((Graphic)val).color = color;
			((TMP_Text)val).alignment = align;
			((TMP_Text)val).enableWordWrapping = false;
			((TMP_Text)val).overflowMode = (TextOverflowModes)1;
			((Graphic)val).raycastTarget = false;
			((TMP_Text)val).text = text;
			return val;
		}

		private static Image Edge(string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 offsetMin, Vector2 offsetMax)
		{
			//IL_0006: 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_001e: 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_002b: Unknown result type (might be due to invalid IL or missing references)
			Image obj = NewImage(name, (Transform)(object)panel, Border);
			RectTransform rectTransform = ((Graphic)obj).rectTransform;
			rectTransform.anchorMin = anchorMin;
			rectTransform.anchorMax = anchorMax;
			rectTransform.offsetMin = offsetMin;
			rectTransform.offsetMax = offsetMax;
			return obj;
		}

		private static Marker NewMarker(Transform parent, Vector2 centre, float size)
		{
			//IL_000c: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: 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)
			//IL_00f4: 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_0101: 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)
			Marker marker = new Marker
			{
				Main = NewImage("Marker", parent, Step)
			};
			RectTransform rectTransform = ((Graphic)marker.Main).rectTransform;
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 1f);
			rectTransform.anchorMax = val;
			rectTransform.anchorMin = val;
			rectTransform.pivot = new Vector2(0.5f, 0.5f);
			rectTransform.anchoredPosition = centre;
			rectTransform.sizeDelta = new Vector2(size, size);
			if ((Object)(object)checkSprite != (Object)null)
			{
				marker.Main.sprite = checkSprite;
				marker.Main.preserveAspect = true;
				return marker;
			}
			((Transform)rectTransform).localRotation = Quaternion.Euler(0f, 0f, 45f);
			marker.Inner = NewImage("Inner", (Transform)(object)rectTransform, PanelBg);
			RectTransform rectTransform2 = ((Graphic)marker.Inner).rectTransform;
			Vector2 val2 = default(Vector2);
			((Vector2)(ref val2))..ctor(0.5f, 0.5f);
			rectTransform2.pivot = val2;
			val = (rectTransform2.anchorMin = (rectTransform2.anchorMax = val2));
			rectTransform2.anchoredPosition = Vector2.zero;
			float num = Mathf.Max(2f, size * 0.14f);
			rectTransform2.sizeDelta = new Vector2(size - num * 2f, size - num * 2f);
			return marker;
		}

		private static void Place(RectTransform rt, float x, float y, float w, float h)
		{
			//IL_0013: 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_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = default(Vector2);
			((Vector2)(ref val))..ctor(0f, 1f);
			rt.anchorMax = val;
			rt.anchorMin = val;
			rt.pivot = new Vector2(0f, 1f);
			rt.anchoredPosition = new Vector2(x, y);
			rt.sizeDelta = new Vector2(w, h);
		}

		private static void Stretch(RectTransform rt)
		{
			//IL_0001: 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)
			//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)
			//IL_001e: 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)
			rt.anchorMin = Vector2.zero;
			rt.anchorMax = Vector2.one;
			Vector2 offsetMin = (rt.offsetMax = Vector2.zero);
			rt.offsetMin = offsetMin;
		}

		private static Color Hex(int r, int g, int b)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			return new Color((float)r / 255f, (float)g / 255f, (float)b / 255f, 1f);
		}

		private static Color Opaque(Color c)
		{
			//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_000c: 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)
			return new Color(c.r, c.g, c.b, 1f);
		}
	}
	internal static class Hud
	{
		private static readonly Color PanelBg = new Color(0.06f, 0.07f, 0.1f, 0.88f);

		private static readonly Color TextMain = new Color(0.96f, 0.96f, 0.98f, 1f);

		private static readonly Color TextDim = new Color(0.66f, 0.69f, 0.76f, 1f);

		private static readonly Color AccentQueue = new Color(0.36f, 0.88f, 0.56f, 1f);

		private static readonly Color AccentOff = new Color(0.62f, 0.64f, 0.7f, 1f);

		private static Texture2D roundedTex;

		private static GUIStyle boxStyle;

		private static GUIStyle titleStyle;

		private static GUIStyle bodyStyle;

		private static GUIStyle bigStyle;

		private static GUIStyle rightStyle;

		private static GUIStyle toastStyle;

		private static float panelAlpha;

		private static float toastAlpha;

		private static float lastTime;

		private static int styleScaleKey = -1;

		public static void Draw(QueueRunner r)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Invalid comparison between Unknown and I4
			//IL_0087: 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_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			Event current = Event.current;
			if (current == null || (int)current.type != 7)
			{
				return;
			}
			float unscaledTime = Time.unscaledTime;
			float num = Mathf.Clamp(unscaledTime - lastTime, 0f, 0.1f);
			lastTime = unscaledTime;
			if (Time.timeScale <= 0f)
			{
				return;
			}
			float s = Mathf.Clamp(DishQueuePlugin.HudScale.Value * (float)Screen.height / 1080f, 0.6f, 3f);
			EnsureStyles(s);
			PickupMode value = DishQueuePlugin.Mode.Value;
			Color accent = ((value == PickupMode.Stack) ? AccentQueue : AccentOff);
			if (!GameHud.Active)
			{
				bool flag = DishQueuePlugin.ShowHud.Value && value == PickupMode.Stack && (r.HeldLabel != null || r.Stacked.Count > 0);
				panelAlpha = Mathf.MoveTowards(panelAlpha, flag ? 1f : 0f, num * 6f);
				if (panelAlpha > 0.01f)
				{
					DrawPanel(r, s, accent, unscaledTime);
				}
				bool flag2 = DishQueuePlugin.ShowHud.Value && unscaledTime < r.ToastUntil && !string.IsNullOrEmpty(r.Toast);
				toastAlpha = Mathf.MoveTowards(toastAlpha, flag2 ? 1f : 0f, num * 5f);
				if (toastAlpha > 0.01f)
				{
					DrawToast(r.Toast, s, accent);
				}
			}
		}

		private static void DrawPanel(QueueRunner r, float s, Color accent, float now)
		{
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: 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_0146: 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_0214: Unknown result type (might be due to invalid IL or missing references)
			//IL_0223: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0262: Unknown result type (might be due to invalid IL or missing references)
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_032f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0351: Unknown result type (might be due to invalid IL or missing references)
			//IL_034a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0378: Unknown result type (might be due to invalid IL or missing references)
			//IL_038f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0388: Unknown result type (might be due to invalid IL or missing references)
			int num = Mathf.Clamp(DishQueuePlugin.MaxExtraDishes.Value, 1, 6);
			float num2 = 330f * s;
			float num3 = 26f * s;
			float num4 = 110f * s + (float)num * num3;
			float num5 = 20f * s;
			float num6 = (float)Screen.height * 0.38f;
			float num7 = Mathf.Clamp01((r.FlashUntil - now) / 1.2f);
			Color color = Color.Lerp(PanelBg, new Color(accent.r * 0.35f, accent.g * 0.35f, accent.b * 0.35f, 0.92f), num7 * 0.7f);
			Box(new Rect(num5, num6, num2, num4), color, panelAlpha);
			Box(new Rect(num5, num6 + 10f * s, 4f * s, num4 - 20f * s), accent, panelAlpha);
			float num8 = 18f * s;
			float num9 = num6 + 10f * s;
			Label(new Rect(num5 + num8, num9, num2 * 0.5f, 22f * s), "ON YOUR TRAY", titleStyle, accent, panelAlpha);
			Label(new Rect(num5 + num2 * 0.5f, num9, num2 * 0.5f - 14f * s, 22f * s), r.Stacked.Count + ((r.HeldLabel != null) ? 1 : 0) + " / " + (DishQueuePlugin.MaxExtraDishes.Value + 1) + " dishes", rightStyle, TextDim, panelAlpha);
			num9 += 24f * s;
			string heldLabel = r.HeldLabel;
			if (heldLabel != null)
			{
				Label(new Rect(num5 + num8, num9, num2 - num8 - 10f * s, 30f * s), "▶  " + heldLabel, bigStyle, TextMain, panelAlpha);
			}
			else
			{
				Label(new Rect(num5 + num8, num9, num2 - num8 - 10f * s, 30f * s), "hands free – next dish is coming", bodyStyle, TextDim, panelAlpha);
			}
			num9 += 36f * s;
			Box(new Rect(num5 + num8, num9, num2 - num8 - 14f * s, Mathf.Max(1f, 1f * s)), new Color(1f, 1f, 1f, 0.12f), panelAlpha);
			num9 += 8f * s;
			Label(new Rect(num5 + num8, num9, num2 * 0.5f, 18f * s), QueueRunner.IsCleanupJob(MealView.CurrentPlayerTask) ? "STACKED  (dirty plates)" : "STACKED  (served to their customer)", titleStyle, TextDim, panelAlpha);
			num9 += 22f * s;
			for (int i = 0; i < num; i++)
			{
				bool flag = i < r.Stacked.Count;
				string text = (flag ? r.Stacked[i].Label : "—");
				Label(new Rect(num5 + num8, num9, 24f * s, num3), (i + 1).ToString(), bodyStyle, flag ? accent : TextDim, panelAlpha);
				Label(new Rect(num5 + num8 + 26f * s, num9, num2 - num8 - 36f * s, num3), text, bodyStyle, flag ? TextMain : TextDim, panelAlpha * (flag ? 1f : 0.55f));
				num9 += num3;
			}
		}

		private static void DrawToast(string text, float s, Color accent)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: 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_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			float num = toastStyle.CalcSize(new GUIContent(text)).x + 44f * s;
			float num2 = 38f * s;
			float num3 = ((float)Screen.width - num) * 0.5f;
			float num4 = (float)Screen.height - 150f * s;
			Box(new Rect(num3, num4, num, num2), PanelBg, toastAlpha);
			Box(new Rect(num3 + 12f * s, num4 + num2 - 5f * s, num - 24f * s, 2f * s), accent, toastAlpha);
			Label(new Rect(num3, num4, num, num2 - 4f * s), text, toastStyle, TextMain, toastAlpha);
		}

		private static void Box(Rect rect, Color color, float alpha)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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_0011: 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_001f: 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)
			Color color2 = GUI.color;
			GUI.color = new Color(color.r, color.g, color.b, color.a * alpha);
			GUI.Box(rect, GUIContent.none, boxStyle);
			GUI.color = color2;
		}

		private static void Label(Rect rect, string text, GUIStyle style, Color color, float alpha)
		{
			//IL_0000: 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_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			Color color2 = GUI.color;
			GUI.color = new Color(1f, 1f, 1f, alpha);
			style.normal.textColor = color;
			GUI.Label(rect, text, style);
			GUI.color = color2;
		}

		private static void EnsureStyles(float s)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Expected O, but got Unknown
			if ((Object)(object)roundedTex == (Object)null)
			{
				roundedTex = MakeRoundedTexture(64, 18);
			}
			int num = Mathf.RoundToInt(s * 100f);
			if (boxStyle == null || num != styleScaleKey)
			{
				styleScaleKey = num;
				int num2 = 18;
				boxStyle = new GUIStyle();
				boxStyle.normal.background = roundedTex;
				boxStyle.border = new RectOffset(num2, num2, num2, num2);
				titleStyle = MakeText(Mathf.RoundToInt(13f * s), (FontStyle)1, (TextAnchor)3);
				bodyStyle = MakeText(Mathf.RoundToInt(17f * s), (FontStyle)0, (TextAnchor)3);
				bigStyle = MakeText(Mathf.RoundToInt(22f * s), (FontStyle)1, (TextAnchor)3);
				rightStyle = MakeText(Mathf.RoundToInt(13f * s), (FontStyle)1, (TextAnchor)5);
				toastStyle = MakeText(Mathf.RoundToInt(19f * s), (FontStyle)1, (TextAnchor)4);
			}
		}

		private static GUIStyle MakeText(int size, FontStyle fontStyle, TextAnchor anchor)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0005: 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)
			//IL_000d: 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_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)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Expected O, but got Unknown
			return new GUIStyle
			{
				fontSize = size,
				fontStyle = fontStyle,
				alignment = anchor,
				wordWrap = false,
				clipping = (TextClipping)1
			};
		}

		private static Texture2D MakeRoundedTexture(int size, int radius)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_000a: Expected O, but got Unknown
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(size, size, (TextureFormat)4, false);
			((Object)val).hideFlags = (HideFlags)61;
			((Texture)val).filterMode = (FilterMode)1;
			((Texture)val).wrapMode = (TextureWrapMode)1;
			for (int i = 0; i < size; i++)
			{
				for (int j = 0; j < size; j++)
				{
					float num = Mathf.Max(Mathf.Max(radius - j, 0), j - (size - 1 - radius));
					float num2 = Mathf.Max(Mathf.Max(radius - i, 0), i - (size - 1 - radius));
					float num3 = Mathf.Sqrt(num * num + num2 * num2);
					float num4 = Mathf.Clamp01((float)radius + 0.5f - num3);
					val.SetPixel(j, i, new Color(1f, 1f, 1f, num4));
				}
			}
			val.Apply();
			return val;
		}
	}
	internal static class Patches
	{
		[HarmonyPatch(typeof(MealView), "CanInteract")]
		private static class LiftHandsFull
		{
			private static void Postfix(MealView __instance, ref bool __result)
			{
				if (__result)
				{
					return;
				}
				try
				{
					if ((Object)(object)R != (Object)null && R.ShouldLiftRestriction(__instance))
					{
						__result = true;
					}
				}
				catch (Exception ex)
				{
					DishQueuePlugin.Logger.LogError((object)("CanInteract hook failed: " + ex));
				}
			}
		}

		[HarmonyPatch(typeof(MealView), "DoInteraction")]
		private static class Pickup
		{
			private static bool Prefix(MealView __instance)
			{
				try
				{
					return (Object)(object)R == (Object)null || R.BeforePickup(__instance);
				}
				catch (Exception ex)
				{
					DishQueuePlugin.Logger.LogError((object)("pickup prefix failed: " + ex));
					return true;
				}
			}

			private static void Postfix(MealView __instance)
			{
				try
				{
					R?.AfterPickup(__instance);
				}
				catch (Exception ex)
				{
					DishQueuePlugin.Logger.LogError((object)("pickup postfix failed: " + ex));
				}
			}
		}

		[HarmonyPatch(typeof(MealView), "CancelPlayerServing")]
		private static class GuardCancel
		{
			private static bool Prefix()
			{
				try
				{
					if ((Object)(object)R == (Object)null)
					{
						return true;
					}
					R.NoteGameCall("CancelPlayerServing");
					if (R.InStackPickup)
					{
						DishQueuePlugin.Logger.LogInfo((object)"blocked CancelPlayerServing during an extra pickup");
						return false;
					}
				}
				catch (Exception)
				{
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(MealView), "CancelPlayerCleanup")]
		private static class GuardCancelCleanup
		{
			private static bool Prefix()
			{
				try
				{
					if ((Object)(object)R == (Object)null)
					{
						return true;
					}
					R.NoteGameCall("CancelPlayerCleanup");
					if (R.InStackPickup)
					{
						DishQueuePlugin.Logger.LogInfo((object)"blocked CancelPlayerCleanup during an extra pickup");
						return false;
					}
				}
				catch (Exception)
				{
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(PlayerHandsAnimator), "ReleaseTrayMeals")]
		private static class GuardRelease
		{
			private static bool Prefix()
			{
				try
				{
					if ((Object)(object)R == (Object)null)
					{
						return true;
					}
					R.NoteGameCall("ReleaseTrayMeals");
					if (R.InStackPickup)
					{
						DishQueuePlugin.Logger.LogInfo((object)"blocked ReleaseTrayMeals during an extra pickup");
						return false;
					}
				}
				catch (Exception)
				{
				}
				return true;
			}
		}

		[HarmonyPatch(typeof(MealView), "HasServeTaskForCustomer")]
		private static class ServeMatch
		{
			private static void Postfix(AgentGhost customer, ref bool __result)
			{
				try
				{
					R?.OnServeQuery(customer, ref __result);
				}
				catch (Exception ex)
				{
					DishQueuePlugin.Logger.LogError((object)("serve hook failed: " + ex));
				}
			}
		}

		[HarmonyPatch]
		private static class FastTray
		{
			private const int MaxSteps = 240;

			private static bool running;

			private static readonly HashSet<IntPtr> started = new HashSet<IntPtr>();

			private static IEnumerable<MethodBase> TargetMethods()
			{
				Type[] nestedTypes = typeof(PlayerHandsAnimator).GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
				foreach (Type type in nestedTypes)
				{
					if (type.Name.Contains("HoldingMealSequence"))
					{
						MethodInfo methodInfo = AccessTools.Method(type, "MoveNext", (Type[])null, (Type[])null);
						if (methodInfo != null)
						{
							yield return methodInfo;
						}
					}
				}
			}

			private static void Postfix(Il2CppObjectBase __instance, ref bool __result, MethodBase __originalMethod)
			{
				if (running)
				{
					return;
				}
				try
				{
					IntPtr pointer = __instance.Pointer;
					if (!__result)
					{
						started.Remove(pointer);
					}
					else if (DishQueuePlugin.FastTrayAnimations.Value && DishQueuePlugin.Mode.Value == PickupMode.Stack && !started.Add(pointer))
					{
						running = true;
						int num = 0;
						while (__result && num < 240)
						{
							__result = (bool)__originalMethod.Invoke(__instance, null);
							num++;
						}
						if (!__result)
						{
							started.Remove(pointer);
						}
						R?.NoteFastTray(__originalMethod.DeclaringType.Name, num, __result);
					}
				}
				catch (Exception ex)
				{
					DishQueuePlugin.Logger.LogError((object)("fast tray animation failed, turning it off: " + (ex.InnerException ?? ex).Message));
					DishQueuePlugin.FastTrayAnimations.Value = false;
				}
				finally
				{
					running = false;
				}
			}
		}

		[HarmonyPatch(typeof(SerializationManager), "Save")]
		private static class ManualSave
		{
			private static void Prefix()
			{
				try
				{
					R?.BeforeSave();
				}
				catch (Exception)
				{
				}
			}
		}

		[HarmonyPatch(typeof(SerializationManager), "AutoSave")]
		private static class AutoSave
		{
			private static void Prefix()
			{
				try
				{
					R?.BeforeSave();
				}
				catch (Exception)
				{
				}
			}
		}

		private static QueueRunner R => QueueRunner.Instance;

		public static void ApplyAll(Harmony harmony)
		{
			Type[] nestedTypes = typeof(Patches).GetNestedTypes(BindingFlags.Public | BindingFlags.NonPublic);
			foreach (Type type in nestedTypes)
			{
				if (type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length != 0)
				{
					try
					{
						harmony.CreateClassProcessor(type).Patch();
						DishQueuePlugin.Logger.LogInfo((object)("patch applied: " + type.Name));
					}
					catch (Exception ex)
					{
						DishQueuePlugin.Logger.LogError((object)("patch FAILED: " + type.Name + ": " + ex.Message));
					}
				}
			}
		}
	}
	public class QueueRunner : MonoBehaviour
	{
		internal class Carried
		{
			public MealView View;

			public StaffTask Task;

			public string Label;

			public float Countdown;

			public Collider[] Colliders;

			public bool[] ColliderWasEnabled;

			public bool HadBody;

			public bool WasKinematic;

			public bool Prepared;
		}

		public static QueueRunner Instance;

		internal readonly List<Carried> Stacked = new List<Carried>();

		internal string Toast;

		internal float ToastUntil;

		internal float FlashUntil;

		internal bool InStackPickup;

		private Carried pending;

		private StaffTask givenJob;

		private Vector3 pendingLocalPos;

		private Quaternion pendingLocalRot;

		private bool pendingHadPose;

		private float freeSince = -1f;

		private float nextSwapAllowed;

		private float verifyAt = -1f;

		private string verifyLabel;

		private float nextHeldRefresh;

		private string heldLabel;

		private PlayerHandsAnimator cachedHands;

		private float nextErrorLog;

		private static StaffTaskQueue cachedQueue;

		private int fastTrayLogs;

		private const float StackGap = 0.004f;

		internal string HeldLabel => heldLabel;

		public QueueRunner(IntPtr ptr)
			: base(ptr)
		{
		}

		private void Awake()
		{
			Instance = this;
		}

		private void Update()
		{
			try
			{
				if (DishQueuePlugin.Mode.Value != PickupMode.Stack)
				{
					if (Stacked.Count > 0)
					{
						DropAll("mode is " + DishQueuePlugin.Mode.Value);
					}
				}
				else
				{
					RefreshHeld();
					DropObsolete();
					VerifyPromotion();
					PromoteWhenFree();
				}
			}
			catch (Exception ex)
			{
				LogError("update failed: " + ex);
			}
		}

		private void LateUpdate()
		{
			try
			{
				LayoutStack();
			}
			catch (Exception ex)
			{
				LogError("layout failed: " + ex);
			}
			GameHud.Tick(this);
		}

		private void OnGUI()
		{
			try
			{
				Hud.Draw(this);
			}
			catch (Exception ex)
			{
				LogError("hud failed: " + ex);
			}
		}

		public bool ShouldLiftRestriction(MealView meal)
		{
			PickupMode value = DishQueuePlugin.Mode.Value;
			if (value == PickupMode.Off)
			{
				return false;
			}
			PlayerHandsAnimator val = LocalHands();
			if ((Object)(object)val == (Object)null || !val.IsHoldingTray)
			{
				return false;
			}
			if (value == PickupMode.Stack && Stacked.Count >= DishQueuePlugin.MaxExtraDishes.Value)
			{
				return false;
			}
			return Reject(meal) == null;
		}

		private string Reject(MealView meal)
		{
			if (!((Component)meal).gameObject.activeInHierarchy)
			{
				return "inactive";
			}
			if (meal.isBeingConsumed)
			{
				return "being eaten";
			}
			if (MealView.CurrentPlayerTask != null && meal.CanBeCleanedUp != IsCleanupJob(MealView.CurrentPlayerTask))
			{
				if (!meal.CanBeCleanedUp)
				{
					return "food while carrying dirty plates";
				}
				return "dirty plate while carrying food";
			}
			if (IsCarriedBySomeone(((Component)meal).transform))
			{
				return "carried by someone";
			}
			if (IsStacked(meal))
			{
				return "already on your tray";
			}
			return null;
		}

		private static bool IsCarriedBySomeone(Transform t)
		{
			Transform parent = t.parent;
			while ((Object)(object)parent != (Object)null)
			{
				if ((Object)(object)((Component)parent).GetComponent<PlayerCharacter>() != (Object)null)
				{
					return true;
				}
				if ((Object)(object)((Component)parent).GetComponent<Agent>() != (Object)null)
				{
					return true;
				}
				if ((Object)(object)((Component)parent).GetComponent<TrayView>() != (Object)null)
				{
					return true;
				}
				parent = parent.parent;
			}
			return false;
		}

		internal bool BeforePickup(MealView view)
		{
			//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_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			if (DishQueuePlugin.Mode.Value != PickupMode.Stack)
			{
				return true;
			}
			PlayerHandsAnimator val = LocalHands();
			if ((Object)(object)val == (Object)null || !val.IsHoldingTray)
			{
				return true;
			}
			if (IsStacked(view))
			{
				return false;
			}
			StaffTask currentPlayerTask = MealView.CurrentPlayerTask;
			if (currentPlayerTask == null)
			{
				return true;
			}
			if (Stacked.Count >= DishQueuePlugin.MaxExtraDishes.Value)
			{
				Notify("Tray full (" + (DishQueuePlugin.MaxExtraDishes.Value + 1) + " dishes)");
				return false;
			}
			MealView val2 = HeldView();
			if ((Object)(object)val2 != (Object)null && ((Il2CppObjectBase)val2).Pointer == ((Il2CppObjectBase)view).Pointer)
			{
				return false;
			}
			if (Reject(view) != null)
			{
				Notify(view.CanBeCleanedUp ? "Dirty plates don't go with food" : "Drop the dirty plates first");
				return false;
			}
			pending = new Carried
			{
				View = val2,
				Task = currentPlayerTask,
				Countdown = MealView.CurrentPlayerCancelCountdown,
				Label = (((Object)(object)val2 != (Object)null) ? ((IsCleanupJob(currentPlayerTask) ? "Dirty " : "") + Pretty(((Object)val2).name)) : "dish")
			};
			pendingHadPose = (Object)(object)val2 != (Object)null;
			if ((Object)(object)val2 != (Object)null)
			{
				pendingLocalPos = ((Component)val2).transform.localPosition;
				pendingLocalRot = ((Component)val2).transform.localRotation;
			}
			MealView.CurrentPlayerTask = null;
			InStackPickup = true;
			bool canBeCleanedUp = view.CanBeCleanedUp;
			bool flag = view.pickUpToServeTask != null;
			givenJob = null;
			StaffTaskQueue queue;
			StaffTask val3 = FindJob(view, canBeCleanedUp, out queue);
			if (!canBeCleanedUp && !flag && val3 != null)
			{
				view.pickUpToServeTask = val3;
				givenJob = val3;
			}
			Log("extra pickup: keeping " + pending.Label + " while the game picks up " + (canBeCleanedUp ? "dirty " : "") + Pretty(((Object)view).name) + " (cancel countdown " + pending.Countdown.ToString("0.0") + ", dish had serve job=" + flag + ", found its " + (canBeCleanedUp ? "cleanup" : "serving") + " job in the staff queue=" + (val3 != null) + ")");
			return true;
		}

		internal void AfterPickup(MealView view)
		{
			//IL_0131: Unknown result type (might be due to invalid IL or missing references)
			//IL_0142: Unknown result type (might be due to invalid IL or missing references)
			if (!InStackPickup)
			{
				return;
			}
			InStackPickup = false;
			Carried carried = pending;
			pending = null;
			if (carried == null)
			{
				return;
			}
			StaffTask currentPlayerTask = MealView.CurrentPlayerTask;
			if (currentPlayerTask == null || ((Il2CppObjectBase)currentPlayerTask).Pointer == ((Il2CppObjectBase)carried.Task).Pointer)
			{
				MealView.CurrentPlayerTask = carried.Task;
				MealView.CurrentPlayerCancelCountdown = carried.Countdown;
				if (givenJob != null && view.pickUpToServeTask != null && ((Il2CppObjectBase)view.pickUpToServeTask).Pointer == ((Il2CppObjectBase)givenJob).Pointer)
				{
					view.pickUpToServeTask = null;
				}
				givenJob = null;
				Log("the game's own pickup refused (now " + ((currentPlayerTask == null) ? "none" : "unchanged") + "); taking the dish myself");
				TakeOntoStack(view, carried.Countdown);
				return;
			}
			givenJob = null;
			PlayerHandsAnimator val = LocalHands();
			if ((Object)(object)val != (Object)null && (Object)(object)val.tray != (Object)null && !IsUnder(((Component)view).transform, val.tray.transform))
			{
				((Component)view).transform.SetParent(val.tray.transform, false);
				if (pendingHadPose)
				{
					((Component)view).transform.localPosition = pendingLocalPos;
					((Component)view).transform.localRotation = pendingLocalRot;
				}
				Rigidbody component = ((Component)view).GetComponent<Rigidbody>();
				if ((Object)(object)component != (Object)null)
				{
					component.isKinematic = true;
				}
				Log("placed " + Pretty(((Object)view).name) + " in the hands myself (the hands animation did not)");
			}
			if ((Object)(object)carried.View == (Object)null)
			{
				Log("extra pickup: could not find the dish that was in hand; its job is kept but it has no model");
			}
			Stacked.Add(carried);
			Prepare(carried);
			FlashUntil = Time.unscaledTime + 1f;
			Log("stacked: " + carried.Label + " (" + Stacked.Count + " on the tray besides the one in hand)");
			LogTray();
		}

		private void TakeOntoStack(MealView view, float countdown)
		{
			bool canBeCleanedUp = view.CanBeCleanedUp;
			string text = (canBeCleanedUp ? "Dirty " : "") + Pretty(((Object)view).name);
			StaffTaskQueue queue;
			StaffTask val = FindJob(view, canBeCleanedUp, out queue);
			if (val == null)
			{
				Log("manual pickup of " + text + ": no " + (canBeCleanedUp ? "cleanup" : "serving") + " job found for it in the staff queue; left where it is");
				Notify(canBeCleanedUp ? (text + " can't be picked up yet") : (text + " has no customer waiting for it"));
				return;
			}
			try
			{
				RemoveJob(queue, val);
			}
			catch (Exception ex)
			{
				Log("manual pickup of " + text + ": removing its job from the staff queue failed: " + ex.Message);
				return;
			}
			MealGhost val2 = null;
			try
			{
				val2 = ((GhostView<MealGhost>)(object)view).MyGhost;
			}
			catch
			{
			}
			string text2 = "no dish data";
			if (canBeCleanedUp)
			{
				text2 = "dirty plate, no processor";
				try
				{
					CleanupMealTask val3 = ((Il2CppObjectBase)val).TryCast<CleanupMealTask>();
					if (val3 != null)
					{
						val3.MealTaken = true;
					}
				}
				catch
				{
				}
				try
				{
					if (val2 != null)
					{
						val2.PlayerAction = (PlayerActions)2;
					}
				}
				catch (Exception ex2)
				{
					Log("could not mark " + text + " as being cleaned up: " + ex2.Message);
				}
			}
			else if (val2 != null)
			{
				text2 = RemoveFromProcessor(val2);
				try
				{
					val2.PlayerAction = (PlayerActions)1;
				}
				catch (Exception ex3)
				{
					Log("could not mark " + text + " as being served: " + ex3.Message);
				}
			}
			view.pickUpToServeTask = null;
			Carried carried = new Carried
			{
				View = view,
				Task = val,
				Countdown = ((countdown > 0f) ? countdown : 10f),
				Label = text
			};
			Stacked.Add(carried);
			Prepare(carried);
			FlashUntil = Time.unscaledTime + 1f;
			Log("manual pickup: stacked " + text + " (job taken from the staff queue, processor: " + text2 + "; " + Stacked.Count + " on the tray besides the one in hand)");
		}

		private static string RemoveFromProcessor(MealGhost meal)
		{
			FoodProcessorGhost val = null;
			try
			{
				GhostReference<FoodProcessorGhost> processorMade = meal.ProcessorMade;
				if (processorMade != (FoodProcessorGhost)null && processorMade.HasValue)
				{
					val = processorMade.Value;
				}
			}
			catch (Exception ex)
			{
				return "lookup failed (" + ex.Message + ")";
			}
			if (val == null)
			{
				return "none recorded";
			}
			try
			{
				val.RemoveMeal(new GhostReference<MealGhost>(meal));
				return "removed";
			}
			catch (Exception ex2)
			{
				try
				{
					return val.Meals.Remove(meal) ? "removed from its list" : "not on it";
				}
				catch
				{
					return "remove failed (" + ex2.Message + ")";
				}
			}
		}

		internal static StaffTask FindJob(MealView view, bool dirty, out StaffTaskQueue queue)
		{
			queue = null;
			MealGhost meal = null;
			try
			{
				meal = ((GhostView<MealGhost>)(object)view).MyGhost;
			}
			catch
			{
			}
			StaffTaskQueue val = QueueFor(meal);
			if (val != null)
			{
				StaffTask obj2 = FindIn(val, view, meal, dirty);
				if (obj2 != null)
				{
					cachedQueue = val;
				}
				queue = val;
				return obj2;
			}
			foreach (Venue item in Resources.FindObjectsOfTypeAll<Venue>())
			{
				StaffTaskQueue val2 = null;
				try
				{
					val2 = (((Object)(object)item != (Object)null) ? item.CurrentTaskQueue : null);
				}
				catch
				{
				}
				if (val2 != null)
				{
					StaffTask val3 = FindIn(val2, view, meal, dirty);
					if (val3 != null)
					{
						cachedQueue = (queue = val2);
						return val3;
					}
				}
			}
			return null;
		}

		private static StaffTaskQueue QueueFor(MealGhost meal)
		{
			try
			{
				VenueOrderReference val = ((meal != null) ? meal.VenueOrderReference : null);
				Venue val2 = ((val != null) ? val.Venue : null);
				StaffTaskQueue val3 = (((Object)(object)val2 != (Object)null) ? val2.CurrentTaskQueue : null);
				if (val3 != null)
				{
					return val3;
				}
			}
			catch
			{
			}
			return cachedQueue;
		}

		private static StaffTask FindIn(StaffTaskQueue q, MealView view, MealGhost meal, bool dirty)
		{
			if (meal != null)
			{
				try
				{
					StaffTask val = (dirty ? q.FindCleanupMealTask(meal) : q.GetServeTaskForMeal(meal));
					if (val != null)
					{
						return val;
					}
				}
				catch
				{
				}
			}
			StaffTask val2 = MatchIn(q.Queue, view, meal, dirty) ?? MatchIn(q.QueueWaiting, view, meal, dirty);
			if (val2 != null)
			{
				return val2;
			}
			List<DelayedTask> delayedQueue = q.DelayedQueue;
			if (delayedQueue == null)
			{
				return null;
			}
			for (int i = 0; i < delayedQueue.Count; i++)
			{
				StaffTask val3 = ((delayedQueue[i] != null) ? delayedQueue[i].Task : null);
				if (val3 != null && IsJobFor(val3, view, meal, dirty))
				{
					return val3;
				}
			}
			return null;
		}

		private static StaffTask MatchIn(List<StaffTask> list, MealView view, MealGhost meal, bool dirty)
		{
			if (list == null)
			{
				return null;
			}
			for (int i = 0; i < list.Count; i++)
			{
				if (list[i] != null && IsJobFor(list[i], view, meal, dirty))
				{
					return list[i];
				}
			}
			return null;
		}

		private static bool IsJobFor(StaffTask task, MealView view, MealGhost meal, bool dirty)
		{
			MealGhost val = null;
			if (dirty)
			{
				CleanupMealTask val2 = ((Il2CppObjectBase)task).TryCast<CleanupMealTask>();
				if (val2 == null)
				{
					return false;
				}
				try
				{
					GhostReference<MealGhost> meal2 = val2.Meal;
					if (meal2 != (MealGhost)null && meal2.HasValue)
					{
						val = meal2.Value;
					}
				}
				catch
				{
				}
			}
			else
			{
				ServeTask val3 = ((Il2CppObjectBase)task).TryCast<ServeTask>();
				if (val3 == null)
				{
					return false;
				}
				val = val3.Meal;
			}
			if (val == null)
			{
				return false;
			}
			if (meal != null)
			{
				return ((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)meal).Pointer;
			}
			IGhostView val4 = default(IGhostView);
			if (((Ghost)val).TryGetLoadedView(ref val4) && val4 != null)
			{
				return ((Il2CppObjectBase)val4).Pointer == ((Il2CppObjectBase)view).Pointer;
			}
			return false;
		}

		private static void RemoveJob(StaffTaskQueue q, StaffTask task)
		{
			q.RemoveTask(task);
			List<DelayedTask> delayedQueue = q.DelayedQueue;
			if (delayedQueue == null)
			{
				return;
			}
			for (int num = delayedQueue.Count - 1; num >= 0; num--)
			{
				StaffTask val = ((delayedQueue[num] != null) ? delayedQueue[num].Task : null);
				if (val != null && ((Il2CppObjectBase)val).Pointer == ((Il2CppObjectBase)task).Pointer)
				{
					delayedQueue.RemoveAt(num);
				}
			}
		}

		internal static bool IsCleanupJob(StaffTask task)
		{
			try
			{
				return task != null && ((Il2CppObjectBase)task).TryCast<CleanupMealTask>() != null;
			}
			catch
			{
				return false;
			}
		}

		internal void OnServeQuery(AgentGhost customer, ref bool result)
		{
			if (((DishQueuePlugin.Mode.Value != PickupMode.Stack) | result) || customer == null || Stacked.Count == 0 || Time.unscaledTime < nextSwapAllowed)
			{
				return;
			}
			int num = -1;
			for (int i = 0; i < Stacked.Count; i++)
			{
				if (IsForCustomer(Stacked[i].Task, customer))
				{
					num = i;
					break;
				}
			}
			if (num >= 0 && IsFocused(customer))
			{
				Swap(num);
				result = MealView.CurrentPlayerTask != null && IsForCustomer(MealView.CurrentPlayerTask, customer);
			}
		}

		private static bool IsForCustomer(StaffTask task, AgentGhost customer)
		{
			ServeTask val = ((task != null) ? ((Il2CppObjectBase)task).TryCast<ServeTask>() : null);
			CustomerGhost val2 = ((val != null) ? val.Customer : null);
			if (val2 != null)
			{
				return ((Il2CppObjectBase)val2).Pointer == ((Il2CppObjectBase)customer).Pointer;
			}
			return false;
		}

		private bool IsFocused(AgentGhost customer)
		{
			try
			{
				IGhostView val = default(IGhostView);
				if (!((Ghost)customer).TryGetLoadedView(ref val) || val == null)
				{
					return true;
				}
				Component val2 = ((Il2CppObjectBase)val).TryCast<Component>();
				if ((Object)(object)val2 == (Object)null)
				{
					return true;
				}
				PlayerManager val3 = default(PlayerManager);
				if (!Singleton<PlayerManager>.InstanceExist(ref val3) || val3.LocalPlayer == null || (Object)(object)val3.LocalPlayer.Character == (Object)null)
				{
					return true;
				}
				FocusRaycaster focus = val3.LocalPlayer.Character.Focus;
				List<GameObject> val4 = (((Object)(object)focus != (Object)null) ? focus.ObjectsInFocus : null);
				if (val4 == null)
				{
					return true;
				}
				int instanceID = ((Object)val2.gameObject).GetInstanceID();
				for (int i = 0; i < val4.Count; i++)
				{
					if ((Object)(object)val4[i] != (Object)null && ((Object)val4[i]).GetInstanceID() == instanceID)
					{
						return true;
					}
				}
				return false;
			}
			catch
			{
				return true;
			}
		}

		private void Swap(int idx)
		{
			PlayerHandsAnimator val = LocalHands();
			Carried carried = Stacked[idx];
			Carried carried2 = new Carried
			{
				View = HeldView(),
				Task = MealView.CurrentPlayerTask,
				Countdown = MealView.CurrentPlayerCancelCountdown
			};
			carried2.Label = (((Object)(object)carried2.View != (Object)null) ? Pretty(((Object)carried2.View).name) : "dish");
			Stacked.RemoveAt(idx);
			if (carried2.Task != null)
			{
				Stacked.Insert(idx, carried2);
				Prepare(carried2);
			}
			Release(carried);
			MealView.CurrentPlayerTask = carried.Task;
			MealView.CurrentPlayerCancelCountdown = carried.Countdown;
			if ((Object)(object)val != (Object)null && (Object)(object)carried.View != (Object)null)
			{
				val.StartHoldingMeal(carried.View);
			}
			nextSwapAllowed = Time.unscaledTime + 0.5f;
			FlashUntil = Time.unscaledTime + 0.8f;
			Log("swapped in " + carried.Label + " for the customer in front of the player (stacked now: " + Stacked.Count + ")");
		}

		private void PromoteWhenFree()
		{
			if (Stacked.Count == 0)
			{
				freeSince = -1f;
				return;
			}
			PlayerHandsAnimator val = LocalHands();
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			if (val.IsHoldingTray || val.IsPlayingMealAnimation || MealView.CurrentPlayerTask != null)
			{
				freeSince = -1f;
				return;
			}
			if (freeSince < 0f)
			{
				freeSince = Time.unscaledTime;
			}
			if (!(Time.unscaledTime - freeSince < DishQueuePlugin.NextDishDelaySeconds.Value))
			{
				Carried carried = Stacked[0];
				Stacked.RemoveAt(0);
				Release(carried);
				MealView.CurrentPlayerTask = carried.Task;
				MealView.CurrentPlayerCancelCountdown = carried.Countdown;
				if ((Object)(object)carried.View != (Object)null)
				{
					val.StartHoldingMeal(carried.View);
				}
				verifyAt = Time.unscaledTime + 0.4f;
				verifyLabel = carried.Label;
				FlashUntil = Time.unscaledTime + 1.2f;
				Log("next dish into hands: " + carried.Label + " (" + Stacked.Count + " still stacked)");
				freeSince = -1f;
			}
		}

		private void VerifyPromotion()
		{
			if (!(verifyAt < 0f) && !(Time.unscaledTime < verifyAt))
			{
				verifyAt = -1f;
				PlayerHandsAnimator val = LocalHands();
				bool flag = (Object)(object)val != (Object)null && val.IsHoldingTray;
				Log("check after moving " + verifyLabel + " into hands: holding=" + flag + " playerJob=" + (MealView.CurrentPlayerTask != null) + (flag ? "  -> it worked" : "  -> the hands did not take it"));
			}
		}

		private void DropObsolete()
		{
			for (int num = Stacked.Count - 1; num >= 0; num--)
			{
				Carried carried = Stacked[num];
				bool flag = (Object)(object)carried.View == (Object)null || (Object)(object)((Component)carried.View).gameObject == (Object)null;
				bool flag2 = false;
				try
				{
					flag2 = carried.Task == null || carried.Task.IsObsolete;
				}
				catch
				{
				}
				if (flag || flag2)
				{
					Stacked.RemoveAt(num);
					if (!flag)
					{
						Release(carried);
						((Component)carried.View).transform.SetParent((Transform)null, true);
					}
					Notify(carried.Label + " is no longer wanted");
					Log("dropped stacked " + carried.Label + ": " + (flag ? "the dish no longer exists" : "its customer is gone"));
				}
			}
		}

		private void DropAll(string why)
		{
			Log("letting go of " + Stacked.Count + " stacked dish(es): " + why);
			foreach (Carried item in Stacked)
			{
				if (!((Object)(object)item.View == (Object)null))
				{
					Release(item);
					((Component)item.View).transform.SetParent((Transform)null, true);
				}
			}
			Stacked.Clear();
		}

		internal void BeforeSave()
		{
			if (Stacked.Count != 0)
			{
				DishQueuePlugin.Logger.LogWarning((object)("the game is saving while " + Stacked.Count + " extra dish(es) are stacked; only the dish in hand is part of the game's own state"));
				Notify("Saving with " + Stacked.Count + " stacked dish(es)");
			}
		}

		internal void NoteFastTray(string sequence, int steps, bool stillRunning)
		{
			if (DishQueuePlugin.VerboseLog.Value && fastTrayLogs < 20)
			{
				fastTrayLogs++;
				string text = (sequence.Contains("Start") ? "take-dish" : (sequence.Contains("Stop") ? "put-down" : sequence));
				Log("sped up the " + text + " animation: finished in " + steps + " extra step(s)" + (stillRunning ? " (still running after the cap)" : ""));
			}
		}

		internal void NoteGameCall(string what)
		{
			if (DishQueuePlugin.VerboseLog.Value && (Stacked.Count > 0 || InStackPickup))
			{
				DishQueuePlugin.Logger.LogInfo((object)("game called " + what + (InStackPickup ? " during an extra pickup" : "") + " (stacked: " + Stacked.Count + ")"));
			}
		}

		private void Prepare(Carried c)
		{
			if (!((Object)(object)c.View == (Object)null) && !c.Prepared)
			{
				c.Colliders = Il2CppArrayBase<Collider>.op_Implicit(((Component)c.View).GetComponentsInChildren<Collider>(true));
				c.ColliderWasEnabled = new bool[c.Colliders.Length];
				for (int i = 0; i < c.Colliders.Length; i++)
				{
					c.ColliderWasEnabled[i] = c.Colliders[i].enabled;
					c.Colliders[i].enabled = false;
				}
				Rigidbody component = ((Component)c.View).GetComponent<Rigidbody>();
				c.HadBody = (Object)(object)component != (Object)null;
				if ((Object)(object)component != (Object)null)
				{
					c.WasKinematic = component.isKinematic;
					component.isKinematic = true;
				}
				PlayerManager val = default(PlayerManager);
				if (Singleton<PlayerManager>.InstanceExist(ref val) && val.LocalPlayer != null && (Object)(object)val.LocalPlayer.Character != (Object)null)
				{
					((Component)c.View).transform.SetParent(((Component)val.LocalPlayer.Character).transform, true);
				}
				c.Prepared = true;
			}
		}

		private void Release(Carried c)
		{
			if ((Object)(object)c.View == (Object)null || !c.Prepared)
			{
				return;
			}
			if (c.Colliders != null)
			{
				for (int i = 0; i < c.Colliders.Length; i++)
				{
					if ((Object)(object)c.Colliders[i] != (Object)null)
					{
						c.Colliders[i].enabled = c.ColliderWasEnabled[i];
					}
				}
			}
			Rigidbody val = (c.HadBody ? ((Component)c.View).GetComponent<Rigidbody>() : null);
			if ((Object)(object)val != (Object)null)
			{
				val.isKinematic = c.WasKinematic;
			}
			c.Prepared = false;
		}

		private void LayoutStack()
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: 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)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: 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)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: 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_0128: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_012e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: 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_0148: Unknown result type (might be due to invalid IL or missing references)
			//IL_014d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: 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_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_0202: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0215: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			if (Stacked.Count == 0)
			{
				return;
			}
			PlayerHandsAnimator val = LocalHands();
			Transform val2 = (((Object)(object)val != (Object)null && (Object)(object)val.tray != (Object)null && val.tray.activeInHierarchy) ? val.tray.transform : null);
			MealView val3 = (((Object)(object)val2 != (Object)null) ? HeldView() : null);
			Vector3 val4;
			float num;
			Vector3 val5;
			if ((Object)(object)val3 != (Object)null && TryGetBounds(((Component)val3).gameObject, out var bounds))
			{
				val4 = ((Bounds)(ref bounds)).center;
				num = ((Bounds)(ref bounds)).max.y;
				val5 = val2.forward;
			}
			else if ((Object)(object)val2 != (Object)null)
			{
				val4 = val2.position;
				num = val2.position.y + 0.01f;
				val5 = val2.forward;
			}
			else
			{
				Camera main = Camera.main;
				if ((Object)(object)main == (Object)null)
				{
					return;
				}
				val4 = ((Component)main).transform.position + ((Component)main).transform.forward * 0.55f - ((Component)main).transform.up * 0.45f;
				num = val4.y;
				val5 = ((Component)main).transform.forward;
			}
			val5 = Vector3.ProjectOnPlane(val5, Vector3.up);
			if (((Vector3)(ref val5)).sqrMagnitude < 0.001f)
			{
				val5 = Vector3.forward;
			}
			for (int i = 0; i < Stacked.Count; i++)
			{
				Carried carried = Stacked[i];
				if (!((Object)(object)carried.View == (Object)null))
				{
					Transform transform = ((Component)carried.View).transform;
					transform.rotation = Quaternion.LookRotation(val5, Vector3.up);
					transform.position = new Vector3(val4.x, num, val4.z);
					if (!TryGetBounds(((Component)carried.View).gameObject, out var bounds2))
					{
						num += 0.05f;
						continue;
					}
					transform.position += new Vector3(val4.x - ((Bounds)(ref bounds2)).center.x, num - ((Bounds)(ref bounds2)).min.y + 0.004f, val4.z - ((Bounds)(ref bounds2)).center.z);
					num += ((Bounds)(ref bounds2)).size.y + 0.004f;
				}
			}
		}

		private static bool TryGetBounds(GameObject go, out Bounds bounds)
		{
			//IL_0001: 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_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)
			bounds = default(Bounds);
			bool flag = false;
			Il2CppArrayBase<Renderer> componentsInChildren = go.GetComponentsInChildren<Renderer>(false);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Renderer val = componentsInChildren[i];
				if (!((Object)(object)val == (Object)null) && val.enabled && !((Object)(object)((Il2CppObjectBase)val).TryCast<ParticleSystemRenderer>() != (Object)null))
				{
					if (!flag)
					{
						bounds = val.bounds;
						flag = true;
					}
					else
					{
						((Bounds)(ref bounds)).Encapsulate(val.bounds);
					}
				}
			}
			return flag;
		}

		private PlayerHandsAnimator LocalHands()
		{
			if ((Object)(object)cachedHands != (Object)null)
			{
				return cachedHands;
			}
			PlayerManager val = default(PlayerManager);
			if (!Singleton<PlayerManager>.InstanceExist(ref val) || val.LocalPlayer == null || (Object)(object)val.LocalPlayer.Character == (Object)null)
			{
				return null;
			}
			cachedHands = ((Component)val.LocalPlayer.Character).GetComponentInChildren<PlayerHandsAnimator>(true);
			return cachedHands;
		}

		private MealView HeldView()
		{
			PlayerHandsAnimator val = LocalHands();
			if ((Object)(object)val == (Object)null || (Object)(object)val.tray == (Object)null)
			{
				return null;
			}
			Transform transform = val.tray.transform;
			for (int i = 0; i < transform.childCount; i++)
			{
				MealView component = ((Component)transform.GetChild(i)).GetComponent<MealView>();
				if ((Object)(object)component != (Object)null && !IsStacked(component))
				{
					return component;
				}
			}
			return null;
		}

		private static bool IsUnder(Transform t, Transform parent)
		{
			Transform val = t;
			while ((Object)(object)val != (Object)null)
			{
				if ((Object)(object)val == (Object)(object)parent)
				{
					return true;
				}
				val = val.parent;
			}
			return false;
		}

		private bool IsStacked(MealView view)
		{
			foreach (Carried item in Stacked)
			{
				if ((Object)(object)item.View != (Object)null && ((Il2CppObjectBase)item.View).Pointer == ((Il2CppObjectBase)view).Pointer)
				{
					return true;
				}
			}
			return false;
		}

		private void RefreshHeld()
		{
			if (!(Time.unscaledTime < nextHeldRefresh))
			{
				nextHeldRefresh = Time.unscaledTime + 0.2f;
				PlayerHandsAnimator val = LocalHands();
				if ((Object)(object)val == (Object)null || !val.IsHoldingTray)
				{
					heldLabel = null;
					return;
				}
				MealView val2 = HeldView();
				heldLabel = (((Object)(object)val2 != (Object)null) ? ((IsCleanupJob(MealView.CurrentPlayerTask) ? "Dirty " : "") + Pretty(((Object)val2).name)) : "your tray");
			}
		}

		private void LogTray()
		{
			if (!DishQueuePlugin.VerboseLog.Value)
			{
				return;
			}
			PlayerHandsAnimator val = LocalHands();
			if (!((Object)(object)val == (Object)null) && !((Object)(object)val.tray == (Object)null))
			{
				List<string> list = new List<string>();
				Transform transform = val.tray.transform;
				for (int i = 0; i < transform.childCount; i++)
				{
					list.Add(((Object)transform.GetChild(i)).name);
				}
				Log("tray now holds: " + string.Join(", ", list) + " | player job set=" + (MealView.CurrentPlayerTask != null));
			}
		}

		internal void Notify(string text)
		{
			Toast = text;
			ToastUntil = Time.unscaledTime + 2.5f;
		}

		private static void Log(string msg)
		{
			if (DishQueuePlugin.VerboseLog.Value)
			{
				DishQueuePlugin.Logger.LogInfo((object)msg);
			}
		}

		private void LogError(string msg)
		{
			if (!(Time.unscaledTime < nextErrorLog))
			{
				nextErrorLog = Time.unscaledTime + 5f;
				DishQueuePlugin.Logger.LogError((object)msg);
			}
		}

		internal static string Pretty(string name)
		{
			name = name.Replace("(Clone)", "").Replace("Variant", "").Trim();
			string[] array = new string[2] { "Dish_", "Drink_" };
			foreach (string text in array)
			{
				if (name.StartsWith(text))
				{
					name = name.Substring(text.Length);
				}
			}
			name = name.Replace('_', ' ').Replace('-', ' ').Trim();
			StringBuilder stringBuilder = new StringBuilder(name.Length + 8);
			for (int j = 0; j < name.Length; j++)
			{
				if (j > 0 && char.IsUpper(name[j]) && char.IsLower(name[j - 1]))
				{
					stringBuilder.Append(' ');
				}
				stringBuilder.Append(name[j]);
			}
			return Regex.Replace(stringBuilder.ToString(), " {2,}", " ");
		}
	}
}