using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Microsoft.CodeAnalysis; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("OrderTabletAssistant")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("OrderTabletAssistant")] [assembly: AssemblyTitle("OrderTabletAssistant")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace OrderTabletAssistant { [BepInPlugin("acesgaminguk.supermarkettogether.ordertabletassistant", "OrderTabletAssistant", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { internal static Plugin Instance; internal static ConfigEntry Enabled; internal static ConfigEntry Mode; internal static ConfigEntry PopulateHotkey; internal static ConfigEntry WhereToCheck; internal static ConfigEntry ShowManualPanel; internal static ConfigEntry PanelScale; internal static ConfigEntry PromptColourChoice; internal static ConfigEntry CustomPromptColour; internal static ConfigEntry PanelX; internal static ConfigEntry PanelY; private Harmony _harmony; private OrderingDevice _activeDevice; private float _lastPopulateTime; private bool _scanInProgress; private GameObject _nativePanel; private RectTransform _nativePanelRect; private TextMeshProUGUI _nativePanelText; private Image _nativePanelImage; private Color _nativePanelOriginalColour; private bool _draggingPanel; private Vector3 _lastMousePosition; private static readonly MethodInfo AddProductBaseMethod = AccessTools.Method(typeof(OrderingDevice), "AddProductbase", (Type[])null, (Type[])null); private static readonly MethodInfo RetrievePricePerBoxMethod = AccessTools.Method(typeof(OrderingDevice), "RetrievePricePerBox", (Type[])null, (Type[])null); private static readonly MethodInfo DestroyUiObjectsMethod = AccessTools.Method(typeof(OrderingDevice), "DestroyUIObjects", (Type[])null, (Type[])null); private static readonly MethodInfo CalculateShoppingListTotalMethod = AccessTools.Method(typeof(OrderingDevice), "CalculateShoppingListTotal", (Type[])null, (Type[])null); private void Awake() { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Expected O, but got Unknown //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Expected O, but got Unknown Instance = this; Enabled = ((BaseUnityPlugin)this).Config.Bind("# General #", "Enable Mod", true, "Turns Order Tablet Assistant on or off."); Mode = ((BaseUnityPlugin)this).Config.Bind("# Order Tablet #", "How to Fill the Order", PopulateMode.Manual, "Manual = press the chosen key. Automatic = fill the order when the tablet opens."); WhereToCheck = ((BaseUnityPlugin)this).Config.Bind("# Order Tablet #", "Where to Check", "Shop Shelves Only", new ConfigDescription("Choose which shelves should be used when creating the order.", (AcceptableValueBase)(object)new AcceptableValueList(new string[3] { "Shop Shelves Only", "Shop and Storage Shelves", "Storage Shelves Only" }), Array.Empty())); PopulateHotkey = ((BaseUnityPlugin)this).Config.Bind("# Controls #", "Manual Fill Key", (KeyCode)114, "The key used to create the order in Manual mode."); ShowManualPanel = ((BaseUnityPlugin)this).Config.Bind("# Display #", "Show Prompt", true, "Shows the Auto Fill prompt while using the tablet in Manual mode."); PanelScale = ((BaseUnityPlugin)this).Config.Bind("# Display #", "Prompt Size", 1f, new ConfigDescription("Changes the size of the prompt.", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 2f), Array.Empty())); PromptColourChoice = ((BaseUnityPlugin)this).Config.Bind("# Display #", "Prompt Colour", "Game Default", new ConfigDescription("Changes the prompt background colour. Game Default keeps the original in-game colour.", (AcceptableValueBase)(object)new AcceptableValueList(new string[8] { "Game Default", "Purple", "Blue", "Orange", "Green", "Red", "Demo Red", "Custom" }), Array.Empty())); CustomPromptColour = ((BaseUnityPlugin)this).Config.Bind("# Display #", "Custom Prompt Colour", new Color(0.36f, 0.16f, 0.46f, 1f), "Used only when Prompt Colour is set to Custom."); PanelX = ((BaseUnityPlugin)this).Config.Bind("# Display #", "Prompt Position X", 28f, "Saved horizontal position of the prompt."); PanelY = ((BaseUnityPlugin)this).Config.Bind("# Display #", "Prompt Position Y", 270f, "Saved vertical position of the prompt."); ((BaseUnityPlugin)this).Logger.LogWarning((object)"============================================="); ((BaseUnityPlugin)this).Logger.LogMessage((object)string.Format("{0} v{1} Initializing...", "Order Tablet Assistant", ((BaseUnityPlugin)this).Info.Metadata.Version)); ((BaseUnityPlugin)this).Logger.LogWarning((object)"============================================="); ((BaseUnityPlugin)this).Logger.LogMessage((object)"Author: AcesGamingUK"); ((BaseUnityPlugin)this).Logger.LogMessage((object)"GitHub: https://github.com/AcesGamingUK/Order-Tablet-Assistant"); ((BaseUnityPlugin)this).Logger.LogMessage((object)("Fill mode: " + Mode.Value)); ((BaseUnityPlugin)this).Logger.LogMessage((object)("Manual fill key: " + ((object)PopulateHotkey.Value/*cast due to .constrained prefix*/).ToString())); ((BaseUnityPlugin)this).Logger.LogMessage((object)("Where to check: " + WhereToCheck.Value)); ((BaseUnityPlugin)this).Logger.LogWarning((object)"============================================="); ((BaseUnityPlugin)this).Logger.LogMessage((object)"Order Tablet Assistant Initialized successfully!"); ((BaseUnityPlugin)this).Logger.LogWarning((object)"============================================="); PanelScale.SettingChanged += delegate { ApplyPanelScale(); }; PromptColourChoice.SettingChanged += delegate { ApplyPanelColour(); }; CustomPromptColour.SettingChanged += delegate { ApplyPanelColour(); }; PopulateHotkey.SettingChanged += delegate { RefreshPanelText(); }; Mode.SettingChanged += delegate { UpdatePanelVisibility(); }; ShowManualPanel.SettingChanged += delegate { UpdatePanelVisibility(); }; Enabled.SettingChanged += delegate { UpdatePanelVisibility(); }; _harmony = new Harmony("acesgaminguk.supermarkettogether.ordertabletassistant"); _harmony.PatchAll(); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } if (Object.op_Implicit((Object)(object)_nativePanel)) { Object.Destroy((Object)(object)_nativePanel); } if (Instance == this) { Instance = null; } } internal void SetActiveDevice(OrderingDevice device) { _activeDevice = device; EnsureNativePanel(); UpdatePanelVisibility(); if (Enabled.Value && Mode.Value == PopulateMode.Automatic) { ((MonoBehaviour)this).StartCoroutine(AutoPopulateNextFrame(device)); } } private IEnumerator AutoPopulateNextFrame(OrderingDevice device) { yield return (object)new WaitForEndOfFrame(); if (Object.op_Implicit((Object)(object)device) && ((Behaviour)device).isActiveAndEnabled) { RequestPopulate(device); } } private void Update() { //IL_003f: Unknown result type (might be due to invalid IL or missing references) UpdatePanelVisibility(); if (Enabled.Value && Mode.Value == PopulateMode.Manual && Object.op_Implicit((Object)(object)_activeDevice) && ((Behaviour)_activeDevice).isActiveAndEnabled) { if (Input.GetKeyDown(PopulateHotkey.Value)) { RequestPopulate(_activeDevice); } HandlePanelDragging(); } } private void EnsureNativePanel() { //IL_0095: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_nativePanel) || (Object)(object)GameCanvas.Instance == (Object)null) { return; } Transform val = ((Component)GameCanvas.Instance).transform.Find("InteractableShowInfo/Container/TitleBCK"); if (!Object.op_Implicit((Object)(object)val)) { ((BaseUnityPlugin)this).Logger.LogWarning((object)"Could not find the native HUD source: InteractableShowInfo/Container/TitleBCK"); return; } _nativePanel = Object.Instantiate(((Component)val).gameObject, ((Component)GameCanvas.Instance).transform); ((Object)_nativePanel).name = "OrderTabletAssistantPanel"; _nativePanelRect = _nativePanel.GetComponent(); _nativePanelRect.anchorMin = new Vector2(0f, 1f); _nativePanelRect.anchorMax = new Vector2(0f, 1f); _nativePanelRect.pivot = new Vector2(0f, 1f); _nativePanelRect.sizeDelta = new Vector2(320f, 60f); _nativePanelRect.anchoredPosition = new Vector2(PanelX.Value, 0f - PanelY.Value); _nativePanelImage = _nativePanel.GetComponent(); if (Object.op_Implicit((Object)(object)_nativePanelImage)) { _nativePanelOriginalColour = ((Graphic)_nativePanelImage).color; } Transform obj = _nativePanel.transform.Find("Title_Text"); _nativePanelText = ((obj != null) ? ((Component)obj).GetComponent() : null); if (!Object.op_Implicit((Object)(object)_nativePanelText)) { _nativePanelText = _nativePanel.GetComponentInChildren(true); } if (Object.op_Implicit((Object)(object)_nativePanelText)) { RectTransform rectTransform = ((TMP_Text)_nativePanelText).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = new Vector2(10f, 4f); rectTransform.offsetMax = new Vector2(-10f, -4f); ((TMP_Text)_nativePanelText).alignment = (TextAlignmentOptions)514; ((TMP_Text)_nativePanelText).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)_nativePanelText).enableAutoSizing = true; ((TMP_Text)_nativePanelText).fontSizeMin = 12f; ((TMP_Text)_nativePanelText).fontSizeMax = 28f; } Graphic[] componentsInChildren = _nativePanel.GetComponentsInChildren(true); for (int i = 0; i < componentsInChildren.Length; i++) { componentsInChildren[i].raycastTarget = false; } ApplyPanelScale(); ApplyPanelColour(); RefreshPanelText(); UpdatePanelVisibility(); } private void ApplyPanelScale() { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_nativePanelRect)) { float num = Mathf.Clamp(PanelScale.Value, 0.5f, 2f); ((Transform)_nativePanelRect).localScale = new Vector3(num, num, 1f); } } private void ApplyPanelColour() { //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: 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_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: 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_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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_011a: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_nativePanelImage)) { Image nativePanelImage = _nativePanelImage; ((Graphic)nativePanelImage).color = (Color)(PromptColourChoice.Value switch { "Purple" => new Color(0.36f, 0.16f, 0.46f, _nativePanelOriginalColour.a), "Blue" => new Color(0f, 0.69f, 0.94f, _nativePanelOriginalColour.a), "Orange" => new Color(0.93f, 0.49f, 0.19f, _nativePanelOriginalColour.a), "Green" => new Color(0.18f, 0.65f, 0.31f, _nativePanelOriginalColour.a), "Red" => new Color(0.85f, 0.1f, 0.1f, _nativePanelOriginalColour.a), "Demo Red" => Color32.op_Implicit(new Color32((byte)64, (byte)2, (byte)2, (byte)Mathf.RoundToInt(_nativePanelOriginalColour.a * 255f))), "Custom" => CustomPromptColour.Value, _ => _nativePanelOriginalColour, }); } } private void RefreshPanelText() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)_nativePanelText)) { ((TMP_Text)_nativePanelText).text = $"Press {PopulateHotkey.Value} to Auto Fill"; } } private void UpdatePanelVisibility() { if (!Object.op_Implicit((Object)(object)_nativePanel)) { if ((Object)(object)GameCanvas.Instance != (Object)null) { EnsureNativePanel(); } return; } bool flag = Enabled.Value && ShowManualPanel.Value && Mode.Value == PopulateMode.Manual && Object.op_Implicit((Object)(object)_activeDevice) && ((Behaviour)_activeDevice).isActiveAndEnabled; if (_nativePanel.activeSelf != flag) { _nativePanel.SetActive(flag); } } private void HandlePanelDragging() { //IL_0037: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_0074: 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) //IL_007e: 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_0085: Unknown result type (might be due to invalid IL or missing references) //IL_0091: 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_009c: Unknown result type (might be due to invalid IL or missing references) //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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)_nativePanel) || !_nativePanel.activeInHierarchy || !Cursor.visible) { _draggingPanel = false; return; } if (Input.GetMouseButtonDown(0) && RectTransformUtility.RectangleContainsScreenPoint(_nativePanelRect, Vector2.op_Implicit(Input.mousePosition), (Camera)null)) { _draggingPanel = true; _lastMousePosition = Input.mousePosition; } if (_draggingPanel && Input.GetMouseButton(0)) { Vector3 val = Input.mousePosition - _lastMousePosition; _lastMousePosition = Input.mousePosition; RectTransform nativePanelRect = _nativePanelRect; nativePanelRect.anchoredPosition += new Vector2(val.x, val.y); PanelX.Value = _nativePanelRect.anchoredPosition.x; PanelY.Value = 0f - _nativePanelRect.anchoredPosition.y; } if (Input.GetMouseButtonUp(0)) { _draggingPanel = false; } } internal void RequestPopulate(OrderingDevice device) { if (!_scanInProgress && !(Time.unscaledTime - _lastPopulateTime < 0.5f) && Object.op_Implicit((Object)(object)device) && !((Object)(object)NPC_Manager.Instance == (Object)null) && !((Object)(object)ProductListing.Instance == (Object)null) && !((Object)(object)GameData.Instance == (Object)null)) { ((MonoBehaviour)this).StartCoroutine(ClearRefreshAndPopulate(device)); } } private IEnumerator ClearRefreshAndPopulate(OrderingDevice device) { _scanInProgress = true; _lastPopulateTime = Time.unscaledTime; try { ClearShoppingListUiAndManager(device); yield return (object)new WaitForEndOfFrame(); yield return null; if (Object.op_Implicit((Object)(object)device) && ((Behaviour)device).isActiveAndEnabled) { PopulateCleanTablet(device); } } finally { _scanInProgress = false; } } private void PopulateCleanTablet(OrderingDevice device) { if (AddProductBaseMethod == null || RetrievePricePerBoxMethod == null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Could not find the ordering tablet list methods. A game update may have changed OrderingDevice."); return; } try { int coveredByStorage = 0; Dictionary dictionary; if (WhereToCheck.Value == "Storage Shelves Only") { dictionary = CountEmptyLabelledStorageSlots(); } else { Dictionary missingItems = CalculateMissingItemsByProduct(); Dictionary storageStock = CountStorageShelfItems(); coveredByStorage = ApplyStorageStockToMissingItems(missingItems, storageStock); dictionary = ConvertMissingItemsToBoxes(missingItems); if (WhereToCheck.Value == "Shop and Storage Shelves") { MergeBoxCounts(dictionary, CountEmptyLabelledStorageSlots()); } } int num = 0; foreach (KeyValuePair item in dictionary) { for (int i = 0; i < item.Value; i++) { AddProductToOrderWithoutRefresh(device, item.Key); num++; } } RefreshOrderTotals(device); string text = BuildModeNotification(WhereToCheck.Value, num, coveredByStorage); ShowNativeNotification(text); ((BaseUnityPlugin)this).Logger.LogMessage((object)("Order Tablet Assistant: " + text.Replace("\n", " | "))); } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogError((object)("Failed to fill ordering tablet: " + ex)); ShowNativeNotification("ORDER TABLET ASSISTANT\nAUTO FILL FAILED - CHECK LOG"); } } private static void AddProductToOrderWithoutRefresh(OrderingDevice device, int productId) { AddProductBaseMethod.Invoke(device, new object[1] { productId }); float num = (float)RetrievePricePerBoxMethod.Invoke(device, new object[1] { productId }); ((Component)GameData.Instance).GetComponent().AddShoppingListProduct(productId, num); } private static void RefreshOrderTotals(OrderingDevice device) { if (CalculateShoppingListTotalMethod != null) { ((MonoBehaviour)device).StartCoroutine((IEnumerator)CalculateShoppingListTotalMethod.Invoke(device, Array.Empty())); } } private static string BuildModeNotification(string mode, int boxesAdded, int coveredByStorage) { if (mode == "Storage Shelves Only") { if (boxesAdded <= 0) { return "ORDER TABLET ASSISTANT\nNO EMPTY LABELLED STORAGE SLOTS"; } return $"ORDER TABLET ASSISTANT\nADDED {boxesAdded} BOXES FOR STORAGE"; } if (mode == "Shop and Storage Shelves") { if (boxesAdded > 0) { return $"ORDER TABLET ASSISTANT\nADDED {boxesAdded} BOXES FOR SHOP AND STORAGE\n{coveredByStorage} PRODUCTS COVERED BY STORAGE"; } if (coveredByStorage > 0) { return $"ORDER TABLET ASSISTANT\nNO BOXES ADDED\n{coveredByStorage} SHOP PRODUCTS COVERED BY STORAGE"; } return "ORDER TABLET ASSISTANT\nSHOP AND STORAGE ARE ALREADY COVERED"; } if (boxesAdded > 0) { return $"ORDER TABLET ASSISTANT\nADDED {boxesAdded} BOXES FOR SHOP SHELVES\n{coveredByStorage} PRODUCTS COVERED BY STORAGE"; } if (coveredByStorage > 0) { return $"ORDER TABLET ASSISTANT\nNO BOXES ADDED\n{coveredByStorage} SHOP PRODUCTS COVERED BY STORAGE"; } return "ORDER TABLET ASSISTANT\nSHOP SHELVES ARE ALREADY COVERED"; } private static Dictionary CalculateMissingItemsByProduct() { Dictionary dictionary = new Dictionary(); GameObject shelvesOBJ = NPC_Manager.Instance.shelvesOBJ; for (int i = 0; i < shelvesOBJ.transform.childCount; i++) { Data_Container component = ((Component)shelvesOBJ.transform.GetChild(i)).GetComponent(); if (!Object.op_Implicit((Object)(object)component) || component.productInfoArray == null) { continue; } int num = component.productInfoArray.Length / 2; for (int j = 0; j < num; j++) { int num2 = component.productInfoArray[j * 2]; int num3 = component.productInfoArray[j * 2 + 1]; if (num2 >= 0 && num3 >= 0) { int maxProductsPerRow = NPC_Manager.Instance.GetMaxProductsPerRow(i, num2); int num4 = Mathf.Max(0, maxProductsPerRow - num3); if (num4 > 0) { AddDictionaryValue(dictionary, num2, num4); } } } } return dictionary; } private static int ApplyStorageStockToMissingItems(Dictionary missingItems, Dictionary storageStock) { int num = 0; foreach (int item in new List(missingItems.Keys)) { int num2 = missingItems[item]; int dictionaryValue = GetDictionaryValue(storageStock, item); if (dictionaryValue >= num2 && num2 > 0) { missingItems[item] = 0; num++; } else if (dictionaryValue > 0) { missingItems[item] = num2 - dictionaryValue; } } return num; } private static Dictionary CountEmptyLabelledStorageSlots() { Dictionary dictionary = new Dictionary(); GameObject storageOBJ = NPC_Manager.Instance.storageOBJ; if (!Object.op_Implicit((Object)(object)storageOBJ)) { return dictionary; } for (int i = 0; i < storageOBJ.transform.childCount; i++) { Data_Container component = ((Component)storageOBJ.transform.GetChild(i)).GetComponent(); if (!Object.op_Implicit((Object)(object)component) || component.productInfoArray == null) { continue; } int num = component.productInfoArray.Length / 2; for (int j = 0; j < num; j++) { int num2 = component.productInfoArray[j * 2]; int num3 = component.productInfoArray[j * 2 + 1]; if (num2 >= 0 && num3 < 0) { AddDictionaryValue(dictionary, num2, 1); } } } return dictionary; } private static void MergeBoxCounts(Dictionary target, Dictionary extra) { foreach (KeyValuePair item in extra) { AddDictionaryValue(target, item.Key, item.Value); } } private static Dictionary CountStorageShelfItems() { Dictionary dictionary = new Dictionary(); GameObject storageOBJ = NPC_Manager.Instance.storageOBJ; if (!Object.op_Implicit((Object)(object)storageOBJ)) { return dictionary; } for (int i = 0; i < storageOBJ.transform.childCount; i++) { Data_Container component = ((Component)storageOBJ.transform.GetChild(i)).GetComponent(); if (!Object.op_Implicit((Object)(object)component) || component.productInfoArray == null) { continue; } int num = component.productInfoArray.Length / 2; for (int j = 0; j < num; j++) { int num2 = component.productInfoArray[j * 2]; int num3 = component.productInfoArray[j * 2 + 1]; if (num2 >= 0 && num3 > 0) { AddDictionaryValue(dictionary, num2, num3); } } } return dictionary; } private static Dictionary ConvertMissingItemsToBoxes(Dictionary missingItems) { Dictionary dictionary = new Dictionary(); foreach (KeyValuePair missingItem in missingItems) { if (missingItem.Value > 0) { int maxItemsPerBox = ProductListing.Instance.productsData[missingItem.Key].maxItemsPerBox; if (maxItemsPerBox > 0) { dictionary[missingItem.Key] = Mathf.CeilToInt((float)missingItem.Value / (float)maxItemsPerBox); } } } return dictionary; } private static void ClearShoppingListUiAndManager(OrderingDevice device) { ManagerBlackboard component = ((Component)GameData.Instance).GetComponent(); GameObject shoppingListParent = component.shoppingListParent; for (int num = (Object.op_Implicit((Object)(object)shoppingListParent) ? shoppingListParent.transform.childCount : 0) - 1; num >= 0; num--) { component.RemoveShoppingListProduct(num); } DestroyUiObjectsMethod?.Invoke(device, Array.Empty()); } private static void ShowNativeNotification(string message) { if ((Object)(object)GameCanvas.Instance == (Object)null) { return; } GameObject val = (Object.op_Implicit((Object)(object)GameCanvas.Instance.importantNotificationPrefab) ? GameCanvas.Instance.importantNotificationPrefab : GameCanvas.Instance.notificationPrefab); Transform val2 = (Object.op_Implicit((Object)(object)GameCanvas.Instance.importantNotificationPrefab) ? GameCanvas.Instance.importantNotificationParentTransform : GameCanvas.Instance.notificationParentTransform); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val2)) { Plugin instance = Instance; if (instance != null) { ((BaseUnityPlugin)instance).Logger.LogWarning((object)"Could not find the game's notification prefab or parent."); } return; } GameObject val3 = Object.Instantiate(val, val2); TextMeshProUGUI val4 = val3.GetComponent(); if (!Object.op_Implicit((Object)(object)val4)) { val4 = val3.GetComponentInChildren(true); } if (Object.op_Implicit((Object)(object)val4)) { ((TMP_Text)val4).text = message; } val3.SetActive(true); } private static void AddDictionaryValue(Dictionary dictionary, int key, int value) { if (!dictionary.ContainsKey(key)) { dictionary[key] = 0; } dictionary[key] += value; } private static int GetDictionaryValue(Dictionary dictionary, int key) { if (!dictionary.TryGetValue(key, out var value)) { return 0; } return value; } } public enum PopulateMode { Manual, Automatic } [HarmonyPatch(typeof(OrderingDevice), "OnEnable")] internal static class OrderingDevice_OnEnable_Patch { private static void Postfix(OrderingDevice __instance) { if (!((Object)(object)Plugin.Instance == (Object)null) && Plugin.Enabled.Value) { Plugin.Instance.SetActiveDevice(__instance); } } } internal static class PluginInfo { public const string Guid = "acesgaminguk.supermarkettogether.ordertabletassistant"; public const string Name = "OrderTabletAssistant"; public const string DisplayName = "Order Tablet Assistant"; public const string Version = "1.0.0"; public const string Author = "AcesGamingUK"; public const string Website = "https://github.com/AcesGamingUK/Order-Tablet-Assistant"; } }