using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("REPO.LoadoutManager")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("REPO mod: pick which purchased items to bring from the truck monitor screen")] [assembly: AssemblyFileVersion("0.1.5.0")] [assembly: AssemblyInformationalVersion("0.1.5")] [assembly: AssemblyProduct("REPO.LoadoutManager")] [assembly: AssemblyTitle("REPO.LoadoutManager")] [assembly: AssemblyVersion("0.1.5.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 REPO.ItemSpawner { [HarmonyPatch(typeof(TruckScreenText), "Awake")] internal static class TruckScreenText_Awake_Patch { private static void Postfix(TruckScreenText __instance) { try { MonitorUI.Build(__instance); } catch (Exception arg) { Plugin.Log.LogError((object)$"[MonitorUI] Failed to build embedded UI: {arg}"); } } } internal static class MonitorUI { private static GameObject _rootGO; private static RectTransform _content; private static ScrollRect _scroll; private static int _selectedCategoryIndex; private static int _selectedRowIndex; private static readonly List _tabImages = new List(); private static readonly List _rowImages = new List(); private static readonly Dictionary _iconCache = new Dictionary(); private static readonly Color TabColor = new Color(1f, 1f, 1f, 0.14f); private static readonly Color TabSelectedColor = new Color(1f, 0.85f, 0.2f, 0.5f); private static readonly Color RowColor = new Color(1f, 1f, 1f, 0.08f); private static readonly Color RowSelectedColor = new Color(1f, 0.85f, 0.2f, 0.35f); private static readonly Color FavoriteTabColor = new Color(0.85f, 0.75f, 0.1f, 0.35f); private static readonly Color FavoriteTabSelectedColor = new Color(1f, 0.9f, 0.15f, 0.65f); private static readonly Color HideTabColor = new Color(0.7f, 0.15f, 0.15f, 0.35f); private static readonly Color HideTabSelectedColor = new Color(1f, 0.2f, 0.2f, 0.65f); private static void GetTabColors(string category, out Color normal, out Color selected) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: 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_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0032: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (category == "Favorite") { normal = FavoriteTabColor; selected = FavoriteTabSelectedColor; } else if (category == "Hide") { normal = HideTabColor; selected = HideTabSelectedColor; } else { normal = TabColor; selected = TabSelectedColor; } } public static void Build(TruckScreenText truckScreenText) { //IL_007e: 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_0089: Expected O, but got Unknown //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00ed: 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_0103: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: 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_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0266: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Expected O, but got Unknown //IL_027c: Unknown result type (might be due to invalid IL or missing references) //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Unknown result type (might be due to invalid IL or missing references) //IL_0356: Unknown result type (might be due to invalid IL or missing references) //IL_035d: Expected O, but got Unknown //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0456: Unknown result type (might be due to invalid IL or missing references) //IL_045d: Expected O, but got Unknown //IL_0464: Unknown result type (might be due to invalid IL or missing references) //IL_046b: Expected O, but got Unknown //IL_048f: 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_04ec: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_04fc: Expected O, but got Unknown //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_0531: Unknown result type (might be due to invalid IL or missing references) //IL_054a: Unknown result type (might be due to invalid IL or missing references) //IL_0559: Unknown result type (might be due to invalid IL or missing references) //IL_0563: Unknown result type (might be due to invalid IL or missing references) Transform val = ((Component)truckScreenText).transform.Find("Canvas"); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)"[MonitorUI] Could not find 'Canvas' child under TruckScreenText."); return; } if ((Object)(object)((Component)val).GetComponent() == (Object)null) { Plugin.Log.LogWarning((object)"[MonitorUI] 'Canvas' child has no Canvas component."); return; } Transform obj = val.Find("Bg"); RectTransform val2 = (RectTransform)(object)((obj is RectTransform) ? obj : null); GameObject val3 = new GameObject("REPO.ItemSpawner.Panel", new Type[2] { typeof(RectTransform), typeof(Canvas) }); _rootGO = val3; RectTransform val4 = (RectTransform)val3.transform; ((Transform)val4).SetParent(val, false); if ((Object)(object)val2 != (Object)null) { val4.anchorMin = val2.anchorMin; val4.anchorMax = val2.anchorMax; val4.anchoredPosition = val2.anchoredPosition + new Vector2(0f, 0.3f); val4.sizeDelta = val2.sizeDelta; } else { val4.anchorMin = Vector2.zero; val4.anchorMax = Vector2.one; val4.anchoredPosition = Vector2.zero; val4.sizeDelta = Vector2.zero; } ((Transform)val4).localScale = new Vector3(0.95f, 0.75f, 1f); Canvas component = val3.GetComponent(); component.overrideSorting = true; component.sortingOrder = 100; ((Graphic)val3.AddComponent()).color = new Color(0f, 0f, 0f, 0.9f); GameObject val5 = new GameObject("Padding", new Type[1] { typeof(RectTransform) }); RectTransform val6 = (RectTransform)val5.transform; ((Transform)val6).SetParent((Transform)(object)val4, false); val6.anchorMin = Vector2.zero; val6.anchorMax = Vector2.one; val6.offsetMin = new Vector2(0.08f, 0.08f); val6.offsetMax = new Vector2(-0.08f, -0.08f); VerticalLayoutGroup obj2 = val5.AddComponent(); ((HorizontalOrVerticalLayoutGroup)obj2).spacing = 0.04f; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj2).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)obj2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)obj2).childForceExpandWidth = true; AddLabel((Transform)(object)val6, "Your Items", 0.2f, 0.26f); AddLabel((Transform)(object)val6, "Arrows: Move Enter: Spawn F: Favorite H: Hide", 0.115f, 0.18f); GameObject val7 = new GameObject("Tabs", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(LayoutElement) }); RectTransform val8 = (RectTransform)val7.transform; ((Transform)val8).SetParent((Transform)(object)val6, false); VerticalLayoutGroup component2 = val7.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component2).spacing = 0.02f; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component2).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)component2).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component2).childControlHeight = true; LayoutElement component3 = val7.GetComponent(); string[] order = ItemCategories.Order; int num = (order.Length + 3) / 4; component3.preferredHeight = 0.26f * (float)num + ((HorizontalOrVerticalLayoutGroup)component2).spacing * (float)(num - 1); component3.minHeight = component3.preferredHeight; component3.flexibleHeight = 0f; _tabImages.Clear(); for (int i = 0; i < order.Length; i += 4) { GameObject val9 = new GameObject($"TabRow{i / 4}", new Type[3] { typeof(RectTransform), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); RectTransform val10 = (RectTransform)val9.transform; ((Transform)val10).SetParent((Transform)(object)val8, false); HorizontalLayoutGroup component4 = val9.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component4).spacing = 0.02f; ((HorizontalOrVerticalLayoutGroup)component4).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component4).childForceExpandHeight = true; ((HorizontalOrVerticalLayoutGroup)component4).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component4).childControlHeight = true; LayoutElement component5 = val9.GetComponent(); component5.preferredHeight = 0.26f; component5.minHeight = 0.26f; component5.flexibleHeight = 0f; for (int j = i; j < Math.Min(i + 4, order.Length); j++) { Image item = CreateTab((Transform)(object)val10, order[j], 0.15f, 0.26f); _tabImages.Add(item); } } GameObject val11 = new GameObject("Scroll", new Type[5] { typeof(RectTransform), typeof(ScrollRect), typeof(Image), typeof(RectMask2D), typeof(LayoutElement) }); RectTransform val12 = (RectTransform)val11.transform; ((Transform)val12).SetParent((Transform)(object)val6, false); ((Graphic)val11.GetComponent()).color = new Color(1f, 1f, 1f, 0.03f); LayoutElement component6 = val11.GetComponent(); component6.flexibleHeight = 1f; component6.minHeight = 0.5f; GameObject val13 = new GameObject("Content", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter) }); _content = (RectTransform)val13.transform; ((Transform)_content).SetParent((Transform)(object)val12, false); _content.anchorMin = new Vector2(0f, 1f); _content.anchorMax = new Vector2(1f, 1f); _content.pivot = new Vector2(0.5f, 1f); _content.sizeDelta = Vector2.zero; VerticalLayoutGroup component7 = val13.GetComponent(); ((HorizontalOrVerticalLayoutGroup)component7).spacing = 0.03f; ((HorizontalOrVerticalLayoutGroup)component7).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)component7).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component7).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component7).childForceExpandWidth = true; ContentSizeFitter component8 = val13.GetComponent(); component8.horizontalFit = (FitMode)0; component8.verticalFit = (FitMode)2; _scroll = val11.GetComponent(); _scroll.content = _content; _scroll.horizontal = false; _scroll.vertical = true; RefreshList(); Canvas.ForceUpdateCanvases(); LayoutRebuilder.ForceRebuildLayoutImmediate(val4); Plugin.Log.LogInfo((object)"[MonitorUI] Embedded panel built (keyboard nav)."); } public static void SetVisible(bool visible) { if ((Object)(object)_rootGO != (Object)null) { _rootGO.SetActive(visible); } } public static void MoveSelection(int delta) { int count = CurrentGrouped().Count; if (count != 0) { _selectedRowIndex = ((_selectedRowIndex + delta) % count + count) % count; UpdateHighlight(); ScrollToSelected(); } } public static void ChangeCategory(int delta) { string[] order = ItemCategories.Order; _selectedCategoryIndex = ((_selectedCategoryIndex + delta) % order.Length + order.Length) % order.Length; _selectedRowIndex = 0; RefreshList(); } public static void ConfirmSelection() { List<(Item, int)> list = CurrentGrouped(); if (_selectedRowIndex >= 0 && _selectedRowIndex < list.Count) { ItemSpawner.RequestSpawn(list[_selectedRowIndex].Item1); RefreshList(); } } public static void CycleFavoriteSelected() { List<(Item, int)> list = CurrentGrouped(); if (_selectedRowIndex >= 0 && _selectedRowIndex < list.Count) { Item item = list[_selectedRowIndex].Item1; int ownedTotal = GetOwnedTotal(item); ItemSpawner.RequestCycleFavorite(item, ownedTotal); } } public static void ToggleHiddenSelected() { List<(Item, int)> list = CurrentGrouped(); if (_selectedRowIndex >= 0 && _selectedRowIndex < list.Count) { Hidden.Toggle(list[_selectedRowIndex].Item1.itemName); RefreshList(); } } private static int GetOwnedTotal(Item item) { if (!((Object)(object)StatsManager.instance != (Object)null)) { return 0; } return StatsManager.instance.GetItemPurchased(item); } private static List<(Item item, int count)> CurrentGrouped() { if ((Object)(object)StatsManager.instance == (Object)null || (Object)(object)ItemManager.instance == (Object)null) { return new List<(Item, int)>(); } string selectedCategory = ItemCategories.Order[_selectedCategoryIndex]; Dictionary remainingByName = (from i in ItemManager.instance.purchasedItems group i by i.itemName).ToDictionary((IGrouping g) => g.Key, (IGrouping g) => g.Count()); IEnumerable source = StatsManager.instance.itemDictionary.Values.Where((Item it) => !it.disabled && GetOwnedTotal(it) > 0); if (selectedCategory == "Hide") { return (from it in source where Hidden.Set.Contains(it.itemName) select (it: it, Remaining(it))).ToList(); } source = source.Where((Item it) => !Hidden.Set.Contains(it.itemName)); if (selectedCategory == "Favorite") { return (from it in source where Favorites.Get(it.itemName) > 0 select (it: it, GetOwnedTotal(it))).ToList(); } return (from it in source where selectedCategory == "All" || ItemCategories.Of(it) == selectedCategory select (item: it, count: Remaining(it)) into g where g.count > 0 select g).ToList(); int Remaining(Item it) { if (!remainingByName.TryGetValue(it.itemName, out var value)) { return 0; } return value; } } private static void AddLabel(Transform parent, string text, float fontSize, float height) { //IL_0032: 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_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Label", new Type[3] { typeof(RectTransform), typeof(TextMeshProUGUI), typeof(LayoutElement) }); val.transform.SetParent(parent, false); TextMeshProUGUI component = val.GetComponent(); ((TMP_Text)component).text = text; ((TMP_Text)component).fontSize = fontSize; ((TMP_Text)component).alignment = (TextAlignmentOptions)513; ((Graphic)component).color = Color.white; ((TMP_Text)component).enableWordWrapping = false; ((TMP_Text)component).overflowMode = (TextOverflowModes)0; LayoutElement component2 = val.GetComponent(); component2.preferredHeight = height; component2.minHeight = height; component2.flexibleHeight = 0f; } private static Image CreateTab(Transform parent, string label, float fontSize, float height) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: 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) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: 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) GameObject val = new GameObject("Tab_" + label, new Type[3] { typeof(RectTransform), typeof(Image), typeof(LayoutElement) }); val.transform.SetParent(parent, false); Image component = val.GetComponent(); ((Graphic)component).color = TabColor; LayoutElement component2 = val.GetComponent(); component2.preferredHeight = height; component2.minHeight = height; component2.flexibleHeight = 0f; GameObject val2 = new GameObject("Label", new Type[2] { typeof(RectTransform), typeof(TextMeshProUGUI) }); val2.transform.SetParent(val.transform, false); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = Vector2.zero; val3.anchorMax = Vector2.one; val3.offsetMin = Vector2.zero; val3.offsetMax = Vector2.zero; TextMeshProUGUI component3 = val2.GetComponent(); ((TMP_Text)component3).text = label; ((TMP_Text)component3).fontSize = fontSize; ((TMP_Text)component3).alignment = (TextAlignmentOptions)514; ((Graphic)component3).color = Color.white; ((TMP_Text)component3).enableAutoSizing = true; ((TMP_Text)component3).fontSizeMin = 0.06f; ((TMP_Text)component3).fontSizeMax = fontSize; ((TMP_Text)component3).enableWordWrapping = true; ((TMP_Text)component3).overflowMode = (TextOverflowModes)3; return component; } public static void RefreshList() { //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Expected O, but got Unknown //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_02c0: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02de: 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_02ee: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0318: 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_03c0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_content == (Object)null || (Object)(object)ItemManager.instance == (Object)null) { return; } for (int num = ((Transform)_content).childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)((Transform)_content).GetChild(num)).gameObject); } _rowImages.Clear(); List<(Item, int)> list = CurrentGrouped(); if (_selectedRowIndex >= list.Count) { _selectedRowIndex = Math.Max(0, list.Count - 1); } if (list.Count == 0) { AddLabel((Transform)(object)_content, "No items in this category", 0.14f, 0.3f); } else { foreach (var item3 in list) { Item item = item3.Item1; int item2 = item3.Item2; GameObject val = new GameObject("Row_" + item.itemName, new Type[4] { typeof(RectTransform), typeof(Image), typeof(HorizontalLayoutGroup), typeof(LayoutElement) }); ((Transform)(RectTransform)val.transform).SetParent((Transform)(object)_content, false); Image component = val.GetComponent(); ((Graphic)component).color = RowColor; _rowImages.Add(component); LayoutElement component2 = val.GetComponent(); component2.preferredHeight = 0.32f; component2.minHeight = 0.32f; component2.flexibleHeight = 0f; HorizontalLayoutGroup component3 = val.GetComponent(); ((LayoutGroup)component3).padding = new RectOffset(0, 0, 0, 0); ((HorizontalOrVerticalLayoutGroup)component3).spacing = 0.04f; ((LayoutGroup)component3).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)component3).childForceExpandHeight = true; ((HorizontalOrVerticalLayoutGroup)component3).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)component3).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)component3).childControlWidth = true; GameObject val2 = new GameObject("Icon", new Type[3] { typeof(RectTransform), typeof(Image), typeof(LayoutElement) }); val2.transform.SetParent(val.transform, false); LayoutElement component4 = val2.GetComponent(); component4.preferredWidth = 0.26f; component4.preferredHeight = 0.26f; component4.minWidth = 0.26f; component4.minHeight = 0.26f; component4.flexibleWidth = 0f; component4.flexibleHeight = 0f; Image component5 = val2.GetComponent(); Sprite icon = GetIcon(item); if ((Object)(object)icon != (Object)null) { component5.sprite = icon; component5.preserveAspect = true; } else { ((Graphic)component5).color = new Color(1f, 1f, 1f, 0.15f); } GameObject val3 = new GameObject("Label", new Type[3] { typeof(RectTransform), typeof(TextMeshProUGUI), typeof(LayoutElement) }); val3.transform.SetParent(val.transform, false); RectTransform val4 = (RectTransform)val3.transform; val4.anchorMin = new Vector2(0f, 0f); val4.anchorMax = new Vector2(1f, 1f); val4.offsetMin = Vector2.zero; val4.offsetMax = Vector2.zero; LayoutElement component6 = val3.GetComponent(); component6.flexibleWidth = 1f; component6.minWidth = 0.5f; component6.minHeight = 0.3f; component6.preferredHeight = 0.3f; TextMeshProUGUI component7 = val3.GetComponent(); int num2 = Favorites.Get(item.itemName); string arg = ((num2 > 0) ? ((num2 == GetOwnedTotal(item)) ? "* " : $"*{num2} ") : ""); ((TMP_Text)component7).text = $"{arg}{item.itemName} x{item2}"; ((TMP_Text)component7).fontSize = 0.16f; ((Graphic)component7).color = Color.white; ((TMP_Text)component7).alignment = (TextAlignmentOptions)513; ((TMP_Text)component7).enableWordWrapping = false; ((TMP_Text)component7).overflowMode = (TextOverflowModes)0; } } UpdateHighlight(); } private static void UpdateHighlight() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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) string[] order = ItemCategories.Order; for (int i = 0; i < _tabImages.Count; i++) { GetTabColors(order[i], out var normal, out var selected); ((Graphic)_tabImages[i]).color = ((i == _selectedCategoryIndex) ? selected : normal); } for (int j = 0; j < _rowImages.Count; j++) { ((Graphic)_rowImages[j]).color = ((j == _selectedRowIndex) ? RowSelectedColor : RowColor); } } private static void ScrollToSelected() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_scroll == (Object)null || _rowImages.Count == 0) { return; } Rect rect = ((RectTransform)((Component)_scroll).transform).rect; float height = ((Rect)(ref rect)).height; rect = _content.rect; float height2 = ((Rect)(ref rect)).height; if (height2 <= height) { _scroll.verticalNormalizedPosition = 1f; return; } float num = height2 / (float)_rowImages.Count; float num2 = (float)_selectedRowIndex * num; float num3 = num2 + num; float num4 = height2 - height; float num5 = (1f - _scroll.verticalNormalizedPosition) * num4; float num6 = num5 + height; float num7 = num5; if (num2 < num5) { num7 = num2; } else if (num3 > num6) { num7 = num3 - height; } num7 = Mathf.Clamp(num7, 0f, num4); _scroll.verticalNormalizedPosition = 1f - num7 / num4; } private static Sprite GetIcon(Item item) { if (_iconCache.TryGetValue(((Object)item).name, out var value)) { return value; } Sprite val = SemiFunc.LoadSpriteFromFile(Path.Combine(Application.persistentDataPath, "Cache", "Icons", "Items", ((Object)item).name.ToLowerInvariant() + ".png")); _iconCache[((Object)item).name] = val; return val; } } [BepInPlugin("kohei.repo.loadoutmanager", "REPO Loadout Manager", "0.1.5")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "kohei.repo.loadoutmanager"; public const string PluginName = "REPO Loadout Manager"; public const string PluginVersion = "0.1.5"; internal static ManualLogSource Log; internal static ConfigEntry DebugDumpsEnabled; internal static ConfigEntry DebugHotkeysEnabled; internal static ConfigEntry DisableFavoritesPatch; private void Awake() { //IL_0075: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; DebugDumpsEnabled = ((BaseUnityPlugin)this).Config.Bind("Debug", "EnableDebugDumps", false, "Log the full item DB and the truck monitor's 3D hierarchy once, for development. Leave off unless debugging."); DebugHotkeysEnabled = ((BaseUnityPlugin)this).Config.Bind("Debug", "EnableDebugHotkeys", false, "Ctrl+F9 = jump straight to Prepare (via Shop), Ctrl+F10 = advance one step (Shop->Prepare->Run->Shop...), Ctrl+F11 = jump straight to a Run level. Off by default - these are level-skip shortcuts for testing, not meant for normal play. Enable only when debugging."); DisableFavoritesPatch = ((BaseUnityPlugin)this).Config.Bind("Debug", "DisableFavoritesPatch", false, "Temporary isolation switch: when true, PunManager.TruckPopulateItemVolumes runs 100% vanilla (no purchasedItems truncation for favorites). Used to test whether that patch is the cause of the belt-slot item loss bug."); Favorites.Load(); new Harmony("kohei.repo.loadoutmanager").PatchAll(); Log.LogInfo((object)"REPO Loadout Manager v0.1.5 loaded."); } } [HarmonyPatch(typeof(ItemManager), "Awake")] internal static class ItemManager_Awake_Patch { private static void Postfix() { //IL_0013: 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_001e: Expected O, but got Unknown if (!((Object)(object)ItemSpawnerRuntime.Instance != (Object)null)) { GameObject val = new GameObject("REPO.ItemSpawner.Runtime"); Object.DontDestroyOnLoad((Object)val); ItemSpawnerRuntime.Instance = val.AddComponent(); Plugin.Log.LogInfo((object)"[ItemSpawner] Runtime UI object created."); } } } internal class ItemSpawnerRuntime : MonoBehaviour { public static ItemSpawnerRuntime Instance; private static readonly FieldRef RunManagerRestartingRef = AccessTools.FieldRefAccess("restarting"); private void OnDisable() { Plugin.Log.LogWarning((object)"[ItemSpawner] Runtime OnDisable - Update() will stop firing."); } private void OnDestroy() { Plugin.Log.LogWarning((object)"[ItemSpawner] Runtime OnDestroy."); } private void Update() { if (ItemSpawnerState.MonitorActive) { if (Input.GetKeyDown((KeyCode)274)) { MonitorUI.MoveSelection(1); } else if (Input.GetKeyDown((KeyCode)273)) { MonitorUI.MoveSelection(-1); } else if (Input.GetKeyDown((KeyCode)275)) { MonitorUI.ChangeCategory(1); } else if (Input.GetKeyDown((KeyCode)276)) { MonitorUI.ChangeCategory(-1); } else if (Input.GetKeyDown((KeyCode)13) || Input.GetKeyDown((KeyCode)271)) { MonitorUI.ConfirmSelection(); } else if (Input.GetKeyDown((KeyCode)102)) { MonitorUI.CycleFavoriteSelected(); } else if (Input.GetKeyDown((KeyCode)104)) { MonitorUI.ToggleHiddenSelected(); } } if (Plugin.DebugHotkeysEnabled.Value && !((Object)(object)RunManager.instance == (Object)null) && (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305))) { if (Input.GetKeyDown((KeyCode)290)) { Plugin.Log.LogInfo((object)$"[Debug] Ctrl+F9 pressed. MenuLevel={SemiFunc.MenuLevel()} MasterOrSP={SemiFunc.IsMasterClientOrSingleplayer()} restarting={RunManagerRestartingRef.Invoke(RunManager.instance)}"); RunManager.instance.ChangeLevel(false, false, (ChangeLevelType)5); ((MonoBehaviour)this).StartCoroutine(AdvanceToPrepareAfterShop()); } else if (Input.GetKeyDown((KeyCode)291)) { Plugin.Log.LogInfo((object)$"[Debug] Ctrl+F10 pressed. MenuLevel={SemiFunc.MenuLevel()} MasterOrSP={SemiFunc.IsMasterClientOrSingleplayer()} restarting={RunManagerRestartingRef.Invoke(RunManager.instance)}"); RunManager.instance.ChangeLevel(false, false, (ChangeLevelType)0); Plugin.Log.LogInfo((object)"[Debug] Advanced one step (Shop->Prepare / Prepare->Run / Run->Shop)."); } else if (Input.GetKeyDown((KeyCode)292)) { Plugin.Log.LogInfo((object)$"[Debug] Ctrl+F11 pressed. MenuLevel={SemiFunc.MenuLevel()} MasterOrSP={SemiFunc.IsMasterClientOrSingleplayer()} restarting={RunManagerRestartingRef.Invoke(RunManager.instance)}"); RunManager.instance.ChangeLevel(false, false, (ChangeLevelType)1); Plugin.Log.LogInfo((object)"[Debug] Jumped straight to a Run level."); } } } private IEnumerator AdvanceToPrepareAfterShop() { float elapsed = 0f; while (!SemiFunc.RunIsShop() && elapsed < 10f) { yield return (object)new WaitForSeconds(0.2f); elapsed += 0.2f; } if (elapsed >= 10f) { Plugin.Log.LogWarning((object)"[Debug] Ctrl+F9: timed out waiting for Shop to load, not advancing to Prepare."); yield break; } yield return (object)new WaitForSeconds(0.5f); RunManager.instance.ChangeLevel(false, false, (ChangeLevelType)0); Plugin.Log.LogInfo((object)"[Debug] Ctrl+F9: Shop -> Prepare."); } } [HarmonyPatch(typeof(TruckScreenText), "Update")] internal static class TruckScreenText_HierarchyDump_Patch { private static bool _dumped; private static void Postfix(TruckScreenText __instance) { if (!_dumped && ItemSpawnerState.MonitorActive && Plugin.DebugDumpsEnabled.Value) { _dumped = true; Plugin.Log.LogInfo((object)"=== TruckScreenText hierarchy dump ==="); DumpRecursive(((Component)__instance).transform, 0); Plugin.Log.LogInfo((object)"=== end hierarchy dump ==="); } } private static void DumpRecursive(Transform t, int depth) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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) string text = new string(' ', depth * 2); Renderer component = ((Component)t).GetComponent(); object obj; if (!((Object)(object)component != (Object)null)) { obj = ""; } else { Bounds bounds = component.bounds; obj = $" [Renderer bounds={((Bounds)(ref bounds)).size}]"; } string text2 = (string)obj; Plugin.Log.LogInfo((object)$"{text}{((Object)t).name} localPos={t.localPosition} localScale={t.localScale}{text2}"); for (int i = 0; i < t.childCount; i++) { DumpRecursive(t.GetChild(i), depth + 1); } } } internal static class ItemSpawnerState { public static bool MonitorActive; } [HarmonyPatch(typeof(RunManager), "ChangeLevel")] internal static class RunManager_ChangeLevel_Diag_Patch { private static void Prefix() { DumpSpawnedItems("BEFORE ChangeLevel"); } private static void Postfix() { ItemSpawnerRuntime instance = ItemSpawnerRuntime.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(DumpAfterDelay()); } } private static IEnumerator DumpAfterDelay() { yield return (object)new WaitForSeconds(1.5f); DumpSpawnedItems("1.5s AFTER ChangeLevel"); } private static void DumpSpawnedItems(string label) { if ((Object)(object)ItemManager.instance == (Object)null) { Plugin.Log.LogInfo((object)("[Diag] " + label + ": ItemManager.instance is null.")); return; } List spawnedItems = ItemManager.instance.spawnedItems; Plugin.Log.LogInfo((object)$"[Diag] {label}: spawnedItems.Count={spawnedItems.Count}"); foreach (ItemAttributes item in spawnedItems) { bool flag = (Object)(object)item != (Object)null; Plugin.Log.LogInfo((object)("[Diag] " + (flag ? "ALIVE" : "DESTROYED") + " - " + (flag ? ((Object)((Component)item).gameObject).name : "?"))); } } } [HarmonyPatch(typeof(RunManager), "GameDirectorStart")] internal static class RunManager_GameDirectorStart_Diag_Patch { private static void Postfix() { Plugin.Log.LogInfo((object)"[Diag] GameDirectorStart fired - run is now officially active (Prepare -> Run, no scene reload)."); DumpSlots("AT GameDirectorStart"); ItemSpawnerRuntime instance = ItemSpawnerRuntime.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(DumpSlotsAfterDelay()); } } private static IEnumerator DumpSlotsAfterDelay() { yield return (object)new WaitForSeconds(1.5f); DumpSlots("1.5s AFTER GameDirectorStart"); } private static void DumpSlots(string label) { if ((Object)(object)Inventory.instance == (Object)null) { Plugin.Log.LogInfo((object)("[Diag] " + label + ": Inventory.instance is null.")); return; } List allSpots = Inventory.instance.GetAllSpots(); for (int i = 0; i < allSpots.Count; i++) { InventorySpot obj = allSpots[i]; ItemEquippable val = ((obj != null) ? obj.CurrentItem : null); Plugin.Log.LogInfo((object)string.Format("[Diag] {0}: slot {1} = {2}", label, i, ((Object)(object)val != (Object)null) ? ((Object)val).name : "EMPTY")); } } } [HarmonyPatch(typeof(StatsManager), "PlayerInventoryUpdate")] internal static class StatsManager_PlayerInventoryUpdate_Diag_Patch { private static void Prefix(string _steamID, string itemName, int spot, bool sync) { Plugin.Log.LogInfo((object)$"[Diag] PlayerInventoryUpdate: steamID={_steamID} itemName='{itemName}' spot={spot} sync={sync}"); } } [HarmonyPatch(typeof(StatsManager), "LoadItemsFromFolder")] internal static class StatsManager_LoadItemsFromFolder_Patch { private static bool _dumped; private static void Postfix(StatsManager __instance) { //IL_0092: Unknown result type (might be due to invalid IL or missing references) if (_dumped || !Plugin.DebugDumpsEnabled.Value) { return; } _dumped = true; Plugin.Log.LogInfo((object)$"=== Item DB dump ({__instance.itemDictionary.Count} items) ==="); foreach (KeyValuePair item in __instance.itemDictionary.OrderBy((KeyValuePair kv) => ((object)Unsafe.As(ref kv.Value.itemType)/*cast due to .constrained prefix*/).ToString())) { Item value = item.Value; Plugin.Log.LogInfo((object)$"[{value.itemType}] key={item.Key} itemName=\"{value.itemName}\" category={ItemCategories.Of(value)} disabled={value.disabled}"); } Plugin.Log.LogInfo((object)"=== end item DB dump ==="); } } internal static class ItemCategories { public const string All = "All"; public const string Favorite = "Favorite"; public const string Hide = "Hide"; private static readonly Dictionary Map = new Dictionary { { (itemType)9, "Weapons" }, { (itemType)7, "Weapons" }, { (itemType)6, "Weapons" }, { (itemType)15, "Weapons" }, { (itemType)11, "Weapons" }, { (itemType)0, "Drones" }, { (itemType)1, "Drones" }, { (itemType)10, "Drones" }, { (itemType)8, "Healing" }, { (itemType)3, "Upgrades" }, { (itemType)4, "Upgrades" }, { (itemType)2, "Vehicles" }, { (itemType)12, "Vehicles" }, { (itemType)14, "Vehicles" }, { (itemType)13, "Tools" }, { (itemType)5, "Other" } }; public static readonly string[] Order = new string[10] { "All", "Favorite", "Hide", "Weapons", "Drones", "Healing", "Upgrades", "Vehicles", "Tools", "Other" }; public static string Of(Item item) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) if (!Map.TryGetValue(item.itemType, out var value)) { return "Other"; } return value; } } [HarmonyPatch(typeof(TruckScreenText), "Update")] internal static class TruckScreenText_Update_Patch { private static readonly FieldRef ScreenActiveRef = AccessTools.FieldRefAccess("screenActive"); private const float MaxInteractDistance = 8f; private static void Postfix(TruckScreenText __instance) { //IL_0036: 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) bool flag = ScreenActiveRef.Invoke(__instance) && !SemiFunc.RunIsShop(); if (flag) { PlayerAvatar val = SemiFunc.PlayerGetLocal(); if ((Object)(object)val == (Object)null) { flag = false; } else if (Vector3.Distance(val.playerTransform.position, ((Component)__instance).transform.position) > 8f) { flag = false; } } ItemSpawnerState.MonitorActive = flag; MonitorUI.SetVisible(flag); } } [HarmonyPatch(typeof(PunManager), "TruckPopulateItemVolumes")] internal static class PunManager_TruckPopulateItemVolumes_Patch { private static void Prefix() { if (!Plugin.DisableFavoritesPatch.Value && !SemiFunc.IsNotMasterClient() && SemiFunc.IsMultiplayer()) { ((MonoBehaviourPun)((Component)PunManager.instance).GetComponent()).photonView.RPC("SyncFavoritesRPC", (RpcTarget)1, new object[2] { Favorites.Counts.Keys.ToArray(), Favorites.Counts.Values.ToArray() }); } } private static void Postfix() { if (!Plugin.DisableFavoritesPatch.Value && !SemiFunc.IsNotMasterClient()) { ItemSpawnerRuntime instance = ItemSpawnerRuntime.Instance; if (instance != null) { ((MonoBehaviour)instance).StartCoroutine(CullNonFavoritedAfterSpawn()); } } } private static IEnumerator CullNonFavoritedAfterSpawn() { yield return (object)new WaitForSeconds(0.3f); ItemManager instance = ItemManager.instance; List spawnedItems = instance.spawnedItems; Dictionary dictionary = new Dictionary(); int num = 0; int num2 = 0; for (int num3 = spawnedItems.Count - 1; num3 >= 0; num3--) { ItemAttributes val = spawnedItems[num3]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val.item == (Object)null)) { string itemName = val.item.itemName; int num4 = Favorites.Get(itemName); int value; int num5 = (dictionary.TryGetValue(itemName, out value) ? value : 0); if (num5 < num4) { dictionary[itemName] = num5 + 1; } else { ItemEquippable component = ((Component)val).GetComponent(); if ((Object)(object)component != (Object)null && (Object)(object)Inventory.instance != (Object)null && Inventory.instance.IsItemEquipped(component)) { dictionary[itemName] = num5 + 1; num2++; } else { PhotonView val2 = (SemiFunc.IsMultiplayer() ? ((Component)val).GetComponent() : null); if ((Object)(object)val2 != (Object)null) { PhotonNetwork.Destroy(val2); } else { Object.Destroy((Object)(object)((Component)val).gameObject); } spawnedItems.RemoveAt(num3); num++; } } } } foreach (KeyValuePair kv in dictionary) { for (int i = 0; i < kv.Value; i++) { int num6 = instance.purchasedItems.FindIndex((Item it) => it.itemName == kv.Key); if (num6 >= 0) { instance.purchasedItems.RemoveAt(num6); } } } if (SemiFunc.IsMultiplayer() && dictionary.Count > 0) { ((MonoBehaviourPun)((Component)PunManager.instance).GetComponent()).photonView.RPC("ConsumeStockBatchRPC", (RpcTarget)1, new object[2] { dictionary.Keys.ToArray(), dictionary.Values.ToArray() }); } Plugin.Log.LogInfo((object)$"[ItemSpawner] Truck auto-spawn: kept {dictionary.Values.Sum()} instance(s) across {dictionary.Count} type(s) ({num2} kept only because already equipped), removed {num} non-favorited vanilla-scattered instance(s)."); MonitorUI.RefreshList(); } } internal static class Favorites { public static readonly Dictionary Counts = new Dictionary(); private static readonly string SaveFilePath = Path.Combine(Paths.ConfigPath, "REPO.LoadoutManager.Favorites.txt"); public static int Get(string itemName) { if (!Counts.TryGetValue(itemName, out var value)) { return 0; } return value; } public static void Set(string itemName, int count) { if (count <= 0) { Counts.Remove(itemName); } else { Counts[itemName] = count; } Save(); } public static int Cycle(string itemName, int ownedCount) { int num = Get(itemName) + 1; if (num > ownedCount) { num = 0; } Set(itemName, num); return num; } public static void ReplaceAll(IEnumerable names, IEnumerable counts) { Counts.Clear(); using IEnumerator enumerator = names.GetEnumerator(); using IEnumerator enumerator2 = counts.GetEnumerator(); while (enumerator.MoveNext() && enumerator2.MoveNext()) { if (enumerator2.Current > 0) { Counts[enumerator.Current] = enumerator2.Current; } } Save(); } public static void Load() { try { if (!File.Exists(SaveFilePath)) { return; } Counts.Clear(); string[] array = File.ReadAllLines(SaveFilePath); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { '=' }); if (array2.Length == 2 && int.TryParse(array2[1], out var result) && result > 0) { Counts[array2[0]] = result; } } Plugin.Log.LogInfo((object)$"[Favorites] Loaded {Counts.Count} saved favorite(s) from disk."); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Favorites] Failed to load saved favorites: " + ex.Message)); } } private static void Save() { try { File.WriteAllLines(SaveFilePath, Counts.Select((KeyValuePair kv) => $"{kv.Key}={kv.Value}")); } catch (Exception ex) { Plugin.Log.LogWarning((object)("[Favorites] Failed to save favorites: " + ex.Message)); } } } internal static class Hidden { public static readonly HashSet Set = new HashSet(); public static bool Toggle(string itemName) { if (Set.Contains(itemName)) { Set.Remove(itemName); return false; } Set.Add(itemName); return true; } } [HarmonyPatch(typeof(PunManager), "Awake")] internal static class PunManager_Awake_Patch { private static void Postfix(PunManager __instance) { if ((Object)(object)((Component)__instance).GetComponent() == (Object)null) { ((Component)__instance).gameObject.AddComponent(); } } } internal class ItemSpawnerNetwork : MonoBehaviourPun { [PunRPC] public void RequestSpawnRPC(string itemName, Vector3 position, Quaternion rotation, PhotonMessageInfo info = default(PhotonMessageInfo)) { //IL_00cf: 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_009d: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClient()) { Item val = ((IEnumerable)StatsManager.instance.itemDictionary.Values).FirstOrDefault((Func)((Item it) => it.itemName == itemName)); if ((Object)(object)val == (Object)null) { Plugin.Log.LogWarning((object)("Spawn request for unknown item: " + itemName)); } else if (!ItemManager.instance.purchasedItems.Any((Item i) => i.itemName == itemName)) { ManualLogSource log = Plugin.Log; string[] obj = new string[5] { "Rejected spawn request - no remaining stock of ", itemName, " (requested by ", null, null }; Player sender = info.Sender; obj[3] = ((sender != null) ? sender.NickName : null); obj[4] = ")"; log.LogWarning((object)string.Concat(obj)); } else { PhotonNetwork.InstantiateRoomObject(((PrefabRef)(object)val.prefab).ResourcePath, position, rotation, (byte)0, (object[])null); ((MonoBehaviourPun)this).photonView.RPC("ConsumeStockRPC", (RpcTarget)0, new object[1] { itemName }); } } } [PunRPC] public void ConsumeStockRPC(string itemName) { List purchasedItems = ItemManager.instance.purchasedItems; int num = purchasedItems.FindIndex((Item i) => i.itemName == itemName); if (num >= 0) { purchasedItems.RemoveAt(num); } else { Plugin.Log.LogWarning((object)("ConsumeStockRPC: no local stock entry found for " + itemName + ".")); } } [PunRPC] public void ConsumeStockBatchRPC(string[] itemNames, int[] counts) { List purchasedItems = ItemManager.instance.purchasedItems; int i; for (i = 0; i < itemNames.Length; i++) { for (int j = 0; j < counts[i]; j++) { int num = purchasedItems.FindIndex((Item it) => it.itemName == itemNames[i]); if (num >= 0) { purchasedItems.RemoveAt(num); } else { Plugin.Log.LogWarning((object)("ConsumeStockBatchRPC: no local stock entry found for " + itemNames[i] + ".")); } } } MonitorUI.RefreshList(); } [PunRPC] public void RequestCycleFavoriteRPC(string itemName, int ownedCount, PhotonMessageInfo info = default(PhotonMessageInfo)) { if (SemiFunc.IsMasterClient()) { int num = Favorites.Cycle(itemName, ownedCount); ((MonoBehaviourPun)this).photonView.RPC("SetFavoriteRPC", (RpcTarget)0, new object[2] { itemName, num }); } } [PunRPC] public void SetFavoriteRPC(string itemName, int count) { Favorites.Set(itemName, count); MonitorUI.RefreshList(); } [PunRPC] public void SyncFavoritesRPC(string[] itemNames, int[] counts) { Favorites.ReplaceAll(itemNames, counts); MonitorUI.RefreshList(); } } internal static class ItemSpawner { public static void RequestSpawn(Item item) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null) { return; } PlayerAvatar val = SemiFunc.PlayerGetLocal(); if ((Object)(object)val == (Object)null) { return; } Vector3 val2 = val.playerTransform.position + val.playerTransform.forward * 1.5f; Quaternion identity = Quaternion.identity; if (!SemiFunc.IsMultiplayer()) { List purchasedItems = ItemManager.instance.purchasedItems; int num = purchasedItems.FindIndex((Item i) => i.itemName == item.itemName); if (num < 0) { Plugin.Log.LogWarning((object)("Blocked spawn - no remaining stock of " + item.itemName)); return; } purchasedItems.RemoveAt(num); Object.Instantiate(((PrefabRef)(object)item.prefab).Prefab, val2, identity); } else { ((MonoBehaviourPun)((Component)PunManager.instance).GetComponent()).photonView.RPC("RequestSpawnRPC", (RpcTarget)2, new object[3] { item.itemName, val2, identity }); } } public static void RequestCycleFavorite(Item item, int ownedCount) { if ((Object)(object)item == (Object)null) { return; } if (!SemiFunc.IsMultiplayer()) { int num = Favorites.Cycle(item.itemName, ownedCount); Plugin.Log.LogInfo((object)$"[MonitorUI] {item.itemName} favorite count -> {num}/{ownedCount}"); MonitorUI.RefreshList(); return; } ItemSpawnerNetwork component = ((Component)PunManager.instance).GetComponent(); if (SemiFunc.IsMasterClient()) { int num2 = Favorites.Cycle(item.itemName, ownedCount); ((MonoBehaviourPun)component).photonView.RPC("SetFavoriteRPC", (RpcTarget)1, new object[2] { item.itemName, num2 }); Plugin.Log.LogInfo((object)$"[MonitorUI] {item.itemName} favorite count -> {num2}/{ownedCount}"); MonitorUI.RefreshList(); } else { ((MonoBehaviourPun)component).photonView.RPC("RequestCycleFavoriteRPC", (RpcTarget)2, new object[2] { item.itemName, ownedCount }); } } } }