using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Numerics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Serialization.Json; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using TMPro; using UnityEngine; using UnityEngine.AI; using UnityEngine.Events; using UnityEngine.SceneManagement; 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("CBra.Taschenhaendler")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.2.0")] [assembly: AssemblyInformationalVersion("1.1.2")] [assembly: AssemblyProduct("CBra.Taschenhaendler")] [assembly: AssemblyTitle("CBra.Taschenhaendler")] [assembly: AssemblyVersion("1.1.2.0")] namespace CBra.Erenshor.Taschenhaendler; internal sealed class ExtraInventorySlotMarker : MonoBehaviour { } internal sealed class InventoryScrollView : MonoBehaviour { private Inventory _inventory; private RectTransform _viewport; private RectTransform _content; private ScrollRect _scrollRect; private GameObject _scrollbarObject; private readonly List _columnOffsets = new List(); private readonly HashSet _displayedSlots = new HashSet(); private float _rowSpacing = 70.5f; private float _slotVisualHeight = 52f; private const float ToolbarHeight = 86f; private RectMask2D _mask; internal static InventoryScrollView Create(Inventory inventory, IReadOnlyList usableSlots) { //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Expected O, but got Unknown if ((Object)(object)inventory == (Object)null || usableSlots == null || usableSlots.Count == 0) { return null; } List list = (from root in usableSlots.Select(InventoryExpansionController.GetSlotRoot) where (Object)(object)root != (Object)null select root).Distinct().ToList(); if (list.Count == 0) { return null; } RectTransform commonParent = default(RectTransform); ref RectTransform reference = ref commonParent; Transform parent = ((Transform)list[0]).parent; reference = (RectTransform)(object)((parent is RectTransform) ? parent : null); if ((Object)(object)commonParent == (Object)null || list.Any((RectTransform root) => (Object)(object)((Transform)root).parent != (Object)(object)commonParent)) { TaschenhaendlerPlugin.ModLog.LogWarning((object)"Inventar-Scrollbereich konnte nicht gebaut werden: Slot-Container haben unterschiedliche Eltern."); return null; } InventoryScrollView componentInChildren = ((Component)commonParent).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren._inventory = inventory; componentInChildren.LayoutSlots(); return componentInChildren; } GameObject val = new GameObject("Taschenhaendler_ScrollViewport", new Type[5] { typeof(RectTransform), typeof(Image), typeof(RectMask2D), typeof(ScrollRect), typeof(InventoryScrollView) }); RectTransform component = val.GetComponent(); ((Transform)component).SetParent((Transform)(object)commonParent, false); ((Transform)component).SetSiblingIndex(Math.Max(0, list.Min((RectTransform root) => ((Transform)root).GetSiblingIndex()))); InventoryScrollView component2 = val.GetComponent(); component2._inventory = inventory; component2._viewport = component; component2._scrollRect = val.GetComponent(); component2._mask = val.GetComponent(); component2.ConfigureGeometry(list); component2.BuildContent(commonParent); component2.BuildScrollbar(commonParent); component2.ConfigureScrollRect(); component2.BuildTools(commonParent); component2.LayoutSlots(); return component2; } internal void LayoutSlots(bool resetScroll = false) { //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021c: 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_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_inventory == (Object)null || (Object)(object)_content == (Object)null || (Object)(object)_viewport == (Object)null) { return; } List list = _inventory.StoredSlots.Where(InventoryExpansionController.IsScrollableInventorySlot).ToList(); List displayedSlots = InventoryToolsState.GetDisplayedSlots(list, _inventory.Empty); _displayedSlots.Clear(); foreach (ItemIcon item in displayedSlots) { _displayedSlots.Add(item); } int num = Math.Max(1, _columnOffsets.Count); int num2 = Math.Max(1, Mathf.CeilToInt((float)displayedSlots.Count / (float)num)); Rect rect = _viewport.rect; float num3 = Math.Max(((Rect)(ref rect)).height, _slotVisualHeight + (float)Math.Max(0, num2 - 1) * _rowSpacing + 4f); _content.SetSizeWithCurrentAnchors((Axis)1, num3); foreach (ItemIcon item2 in list) { RectTransform slotRoot = InventoryExpansionController.GetSlotRoot(item2); if (!((Object)(object)slotRoot == (Object)null)) { ((Transform)slotRoot).SetParent((Transform)(object)_content, false); slotRoot.anchorMin = new Vector2(0.5f, 1f); slotRoot.anchorMax = new Vector2(0.5f, 1f); slotRoot.pivot = new Vector2(0.5f, 0.5f); } } for (int i = 0; i < displayedSlots.Count; i++) { RectTransform slotRoot2 = InventoryExpansionController.GetSlotRoot(displayedSlots[i]); if (!((Object)(object)slotRoot2 == (Object)null)) { int index = i % num; int num4 = i / num; slotRoot2.anchoredPosition = new Vector2(_columnOffsets[index], 0f - (_slotVisualHeight * 0.5f + 2f + (float)num4 * _rowSpacing)); } } rect = _viewport.rect; bool flag = num3 > ((Rect)(ref rect)).height + 1f; if ((Object)(object)_scrollbarObject != (Object)null) { _scrollbarObject.SetActive(flag); } if (resetScroll) { ScrollRect scrollRect = _scrollRect; if (scrollRect != null) { scrollRect.StopMovement(); } _content.anchoredPosition = Vector2.zero; } else if (!flag) { _content.anchoredPosition = Vector2.zero; } Canvas.ForceUpdateCanvases(); UpdateVisibility(); } private void ConfigureGeometry(IReadOnlyList roots) { //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_0230: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02f6: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0386: 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_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Unknown result type (might be due to invalid IL or missing references) List list = (from root in roots select root.anchoredPosition.x into value orderby value select value).ToList(); List list2 = new List(); foreach (float x in list) { if (list2.All((float existing) => Mathf.Abs(existing - x) > 5f)) { list2.Add(x); } } if (list2.Count == 0) { list2.AddRange(new float[3] { -67f, 0f, 67f }); } float num = (list2.First() + list2.Last()) * 0.5f; _columnOffsets.Clear(); foreach (float item in list2) { _columnOffsets.Add(item - num); } List list3 = (from value in roots.Select((RectTransform root) => root.anchoredPosition.y).Distinct() orderby value descending select value).ToList(); if (list3.Count > 1) { List list4 = new List(); for (int num2 = 1; num2 < list3.Count; num2++) { float num3 = list3[num2 - 1] - list3[num2]; if (num3 > 10f) { list4.Add(num3); } } if (list4.Count > 0) { _rowSpacing = list4.OrderBy((float value) => value).ElementAt(list4.Count / 2); } } RectTransform val = roots[0]; Rect rect = val.rect; _slotVisualHeight = Math.Max(40f, ((Rect)(ref rect)).height * Math.Abs(((Transform)val).localScale.y)); float num4 = roots.Min((RectTransform root) => root.anchoredPosition.x); float num5 = roots.Max((RectTransform root) => root.anchoredPosition.x); float num6 = roots.Min((RectTransform root) => root.anchoredPosition.y); float num7 = roots.Max((RectTransform root) => root.anchoredPosition.y); rect = val.rect; float num8 = ((Rect)(ref rect)).width * Math.Abs(((Transform)val).localScale.x); float num9 = num5 - num4 + num8 + 12f; float num10 = num7 - num6 + _slotVisualHeight + 8f; float num11 = Math.Max(_slotVisualHeight * 3f, num10 - 86f); float num12 = (num6 + num7) * 0.5f; _viewport.anchorMin = val.anchorMin; _viewport.anchorMax = val.anchorMax; _viewport.pivot = new Vector2(0.5f, 0.5f); _viewport.anchoredPosition = new Vector2((num4 + num5) * 0.5f, num12 - 43f); _viewport.sizeDelta = new Vector2(num9, num11); Image component = ((Component)_viewport).GetComponent(); ((Graphic)component).color = new Color(0f, 0f, 0f, 0.001f); ((Graphic)component).raycastTarget = true; } private void BuildContent(RectTransform commonParent) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown //IL_004c: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Content", new Type[1] { typeof(RectTransform) }); _content = val.GetComponent(); ((Transform)_content).SetParent((Transform)(object)_viewport, false); _content.anchorMin = new Vector2(0f, 1f); _content.anchorMax = new Vector2(1f, 1f); _content.pivot = new Vector2(0.5f, 1f); _content.anchoredPosition = Vector2.zero; RectTransform content = _content; Rect rect = _viewport.rect; content.sizeDelta = new Vector2(0f, ((Rect)(ref rect)).height); } private void BuildScrollbar(RectTransform commonParent) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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_008f: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00da: 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_0132: 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_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_017c: 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) _scrollbarObject = new GameObject("Taschenhaendler_Scrollbar", new Type[3] { typeof(RectTransform), typeof(Image), typeof(Scrollbar) }); RectTransform component = _scrollbarObject.GetComponent(); ((Transform)component).SetParent((Transform)(object)commonParent, false); component.anchorMin = _viewport.anchorMin; component.anchorMax = _viewport.anchorMax; component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = _viewport.anchoredPosition + new Vector2(_viewport.sizeDelta.x * 0.5f - 5f, 0f); component.sizeDelta = new Vector2(9f, _viewport.sizeDelta.y); ((Graphic)_scrollbarObject.GetComponent()).color = new Color(0.02f, 0.02f, 0.02f, 0.7f); GameObject val = new GameObject("Handle", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform component2 = val.GetComponent(); ((Transform)component2).SetParent((Transform)(object)component, false); component2.anchorMin = Vector2.zero; component2.anchorMax = Vector2.one; component2.offsetMin = new Vector2(1f, 1f); component2.offsetMax = new Vector2(-1f, -1f); Image component3 = val.GetComponent(); ((Graphic)component3).color = new Color(0.72f, 0.55f, 0.22f, 0.95f); Scrollbar component4 = _scrollbarObject.GetComponent(); component4.handleRect = component2; ((Selectable)component4).targetGraphic = (Graphic)(object)component3; component4.direction = (Direction)2; component4.numberOfSteps = 0; _scrollRect.verticalScrollbar = component4; } private void BuildTools(RectTransform commonParent) { //IL_0008: 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_0028: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: 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) Vector2 anchoredPosition = default(Vector2); ((Vector2)(ref anchoredPosition))..ctor(_viewport.anchoredPosition.x, _viewport.anchoredPosition.y + _viewport.sizeDelta.y * 0.5f + 43f); InventoryToolsPanel.Create(_inventory, this, commonParent, _viewport.anchorMin, _viewport.anchorMax, anchoredPosition, new Vector2(_viewport.sizeDelta.x, 82f)); } private void ConfigureScrollRect() { _scrollRect.content = _content; _scrollRect.viewport = _viewport; _scrollRect.horizontal = false; _scrollRect.vertical = true; _scrollRect.movementType = (MovementType)2; _scrollRect.inertia = true; _scrollRect.decelerationRate = 0.135f; _scrollRect.scrollSensitivity = TaschenhaendlerPlugin.Instance.ScrollSensitivity.Value; _scrollRect.verticalScrollbarVisibility = (ScrollbarVisibility)0; ((UnityEvent)(object)_scrollRect.onValueChanged).AddListener((UnityAction)delegate { UpdateVisibility(); }); } private void UpdateVisibility() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: 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) if ((Object)(object)_inventory == (Object)null || (Object)(object)_viewport == (Object)null) { return; } Rect worldRect = GetWorldRect(_viewport); foreach (ItemIcon item in _inventory.StoredSlots.Where(InventoryExpansionController.IsScrollableInventorySlot)) { RectTransform slotRoot = InventoryExpansionController.GetSlotRoot(item); bool num = _displayedSlots.Contains(item); bool flag = num && (Object)(object)slotRoot != (Object)null && ((Rect)(ref worldRect)).Overlaps(GetWorldRect(slotRoot), true); bool flag2 = num && (flag || item.dragging); BoxCollider2D component = ((Component)item).GetComponent(); if ((Object)(object)component != (Object)null) { ((Behaviour)component).enabled = flag2; } Image component2 = ((Component)item).GetComponent(); if ((Object)(object)component2 != (Object)null) { ((Graphic)component2).raycastTarget = flag2; } if ((Object)(object)slotRoot != (Object)null) { CanvasGroup obj = ((Component)slotRoot).GetComponent() ?? ((Component)slotRoot).gameObject.AddComponent(); obj.alpha = (flag2 ? 1f : 0f); obj.blocksRaycasts = flag2; } } } private void LateUpdate() { if (!((Object)(object)_inventory == (Object)null) && !((Object)(object)_mask == (Object)null)) { bool flag = _inventory.StoredSlots.Where(InventoryExpansionController.IsScrollableInventorySlot).Any((ItemIcon slot) => slot.dragging); if (((Behaviour)_mask).enabled == flag) { ((Behaviour)_mask).enabled = !flag; UpdateVisibility(); } } } private static Rect GetWorldRect(RectTransform rectTransform) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) Vector3[] array = (Vector3[])(object)new Vector3[4]; rectTransform.GetWorldCorners(array); return Rect.MinMaxRect(array[0].x, array[0].y, array[2].x, array[2].y); } } internal sealed class SaveIsolationState { internal bool CanProceed = true; internal bool Prepared; internal List Extras; internal List HiddenExpansionItems; internal Dictionary HotkeyIndices = new Dictionary(); } internal sealed class HiddenExpansionItemState { internal ItemIcon Slot; internal Item Item; internal int Quantity; } internal static class InventoryExpansionController { private sealed class IOExceptionLikeException : Exception { } private static Inventory _inventory; private static ItemIcon _trashSlot; private static readonly List ExtraSlots = new List(); private static InventoryScrollView _scrollView; private static CharacterProgress _loadedProgress; private static readonly HashSet UnresolvedOverflowIndices = new HashSet(); private static bool _sidecarAlreadyCommittedForSave; private static bool _nativeSaveProbeActive; private static bool _nativeSaveSucceeded; private static bool _restoringPendingExpansionItems; private static bool _pendingRecoveryNoticeShown; internal static RectTransform GetSlotRoot(ItemIcon slot) { object obj; if (slot == null) { obj = null; } else { Transform transform = ((Component)slot).transform; obj = ((transform != null) ? transform.parent : null); } return (RectTransform)((obj is RectTransform) ? obj : null); } internal static bool IsReservedUnresolvedSlot(ItemIcon slot) { int num = ExtraSlots.IndexOf(slot); if (num >= 0) { return UnresolvedOverflowIndices.Contains(num); } return false; } internal static bool IsScrollableInventorySlot(ItemIcon slot) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)slot != (Object)null && (int)slot.ThisSlotType == 0 && !slot.TrashSlot && !slot.VendorSlot && !slot.LootSlot && !slot.BankSlot && !slot.DisplayOnly && !slot.NotInInventory) { return !slot.CosmeticOnly; } return false; } internal static void RefreshLayout() { _scrollView?.LayoutSlots(); } internal static void RestorePendingExpansionItems() { if (_restoringPendingExpansionItems || (Object)(object)_inventory == (Object)null || _loadedProgress == null || (Object)(object)MerchantController.ExpansionItem == (Object)null) { return; } long num = Math.Max(0L, _loadedProgress.PurchasedCount - _loadedProgress.AppliedCount); long num2 = 0L; foreach (ItemIcon storedSlot in _inventory.StoredSlots) { if ((Object)(object)storedSlot != (Object)null && TaschenhaendlerPlugin.IsExpansion(storedSlot.MyItem)) { num2 = checked(num2 + Math.Max(1L, storedSlot.Quantity)); } } long num3 = Math.Max(0L, num - num2); if (num3 == 0L) { _pendingRecoveryNoticeShown = false; return; } _restoringPendingExpansionItems = true; long num4 = 0L; try { foreach (ItemIcon item in _inventory.StoredSlots.Where((ItemIcon entry) => (Object)(object)entry != (Object)null && TaschenhaendlerPlugin.IsExpansion(entry.MyItem))) { if (num3 <= 0) { break; } long val = int.MaxValue - Math.Max(0, item.Quantity); int num5 = (int)Math.Min(num3, val); if (num5 > 0) { item.Quantity += num5; num3 -= num5; num4 += num5; item.UpdateSlotImage(); } } foreach (ItemIcon item2 in _inventory.StoredSlots.Where((ItemIcon entry) => IsUsableEmptyInventorySlot(entry)).ToList()) { if (num3 <= 0) { break; } int num6 = (int)((num3 > int.MaxValue) ? int.MaxValue : num3); item2.MyItem = MerchantController.ExpansionItem; item2.Quantity = num6; num3 -= num6; num4 += num6; item2.UpdateSlotImage(); } if (num4 > 0) { _inventory.UpdatePlayerInventory(); TaschenhaendlerPlugin.NotifyPlayer(ModLocalization.Format("{0} bereits bezahlte Inventarerweiterung(en) wurden aus dem geschützten Kaufstand wiederhergestellt.", "{0} previously purchased inventory expansion(s) were restored from protected progress.", num4)); } if (num3 > 0 && !_pendingRecoveryNoticeShown) { _pendingRecoveryNoticeShown = true; TaschenhaendlerPlugin.NotifyPlayer(ModLocalization.Format("Für {0} bezahlte Erweiterung(en) ist noch kein freier Inventarplatz vorhanden. Räume einen Platz frei; die Wiederherstellung wird beim nächsten Laden erneut versucht.", "There is no free inventory slot yet for {0} purchased expansion(s). Free one slot; restoration will be retried on the next load.", num3)); } } finally { _restoringPendingExpansionItems = false; } } internal static bool SaveNativeAfterSidecarCommit() { _sidecarAlreadyCommittedForSave = true; _nativeSaveProbeActive = true; _nativeSaveSucceeded = false; try { if ((Object)(object)GameData.GM == (Object)null) { return false; } try { GameData.GM.SaveGameData(false); } catch (Exception ex) { if (!_nativeSaveSucceeded) { throw; } TaschenhaendlerPlugin.ModLog.LogWarning((object)("Der Charakterstand wurde gespeichert, aber ein nachgelagerter Erenshor-Speicherschritt meldete einen Fehler: " + ex.Message)); } return _nativeSaveSucceeded; } finally { _nativeSaveProbeActive = false; _sidecarAlreadyCommittedForSave = false; } } internal static void ReportNativeSaveResult(bool succeeded) { if (_nativeSaveProbeActive) { _nativeSaveSucceeded = succeeded; } } internal static void Initialize(Inventory inventory) { if ((Object)(object)inventory == (Object)null || !inventory.isPlayer) { return; } if ((Object)(object)_inventory != (Object)(object)inventory) { _inventory = inventory; _trashSlot = ((IEnumerable)inventory.StoredSlots).FirstOrDefault((Func)((ItemIcon slot) => (Object)(object)slot != (Object)null && slot.TrashSlot)); ExtraSlots.Clear(); ExtraSlots.AddRange(inventory.StoredSlots.Where(delegate(ItemIcon slot) { RectTransform slotRoot = GetSlotRoot(slot); return (Object)(object)slotRoot != (Object)null && (Object)(object)((Component)slotRoot).GetComponent() != (Object)null; })); _scrollView = null; _loadedProgress = null; _pendingRecoveryNoticeShown = false; } List usableSlots = inventory.StoredSlots.Where(IsScrollableInventorySlot).ToList(); if (_scrollView == null) { _scrollView = InventoryScrollView.Create(inventory, usableSlots); } RebuildAllSlots(); } internal static bool CaptureCurrentBeforeCharacterSwitch() { if (_loadedProgress == null || (Object)(object)_inventory == (Object)null) { return true; } CaptureOverflow(_loadedProgress); bool num = ProgressStore.Save(); if (!num) { TaschenhaendlerPlugin.NotifyPlayer(ModLocalization.Text("Charakterwechsel abgebrochen: Das Zusatzinventar konnte nicht gespeichert werden.", "Character switch cancelled: the extra inventory could not be saved.")); } return num; } internal static void ClearLoadedCharacter() { if ((Object)(object)_inventory != (Object)null) { EnsureExtraSlotCount(0); } _loadedProgress = null; UnresolvedOverflowIndices.Clear(); _pendingRecoveryNoticeShown = false; } internal static void LoadCharacter(CharacterProgress progress) { if ((Object)(object)GameData.PlayerInv == (Object)null || progress == null) { return; } Initialize(GameData.PlayerInv); _loadedProgress = progress; UnresolvedOverflowIndices.Clear(); foreach (ItemIcon extraSlot in ExtraSlots) { if ((Object)(object)extraSlot != (Object)null) { extraSlot.assignedHotkey = null; } } EnsureExtraSlotCount(GetDesiredExtraSlotCount(progress)); MerchantController.RefreshOffer(); } internal static void FinishCharacterLoad(CharacterProgress progress) { if ((Object)(object)_inventory == (Object)null || progress == null) { return; } for (int i = 0; i < ExtraSlots.Count; i++) { StoredItem storedItem = ((i < progress.Overflow.Count) ? progress.Overflow[i] : null); ItemIcon slot = ExtraSlots[i]; if (storedItem == null || string.IsNullOrEmpty(storedItem.Id)) { SetSlot(slot, _inventory.Empty, 0); continue; } ItemDatabase itemDB = GameData.ItemDB; Item val = ((itemDB != null) ? itemDB.GetItemByID(storedItem.Id) : null); if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)_inventory.Empty) { TaschenhaendlerPlugin.ModLog.LogWarning((object)$"Zusatzslot {i} verweist auf unbekanntes Item '{storedItem.Id}'. Der Eintrag bleibt in der Sidecar-Datei erhalten."); UnresolvedOverflowIndices.Add(i); SetSlot(slot, _inventory.Empty, 0); } else { SetSlot(slot, val, Math.Max(1, storedItem.Quantity)); } } _inventory.UpdatePlayerInventory(); RestorePendingExpansionItems(); _scrollView?.LayoutSlots(); } internal static void FinishHotkeyLoad(CharacterProgress progress) { if (progress != null && !((Object)(object)GameData.GM?.HKManager == (Object)null)) { RestoreHotkeyList(GameData.GM.HKManager.FirstHotkeys, progress.FirstExtraHotkeys); RestoreHotkeyList(GameData.GM.HKManager.SecondHotkeys, progress.SecondExtraHotkeys); } } internal static bool TryUseExpansion(ItemIcon sourceSlot) { CharacterProgress current = ProgressStore.Current; if ((Object)(object)_inventory == (Object)null || current == null || (Object)(object)sourceSlot == (Object)null) { TaschenhaendlerPlugin.NotifyPlayer(ModLocalization.Text("Kein aktiver Charakterfortschritt gefunden.", "No active character progress was found.")); return false; } if (sourceSlot.VendorSlot || !_inventory.StoredSlots.Contains(sourceSlot) || !TaschenhaendlerPlugin.IsExpansion(sourceSlot.MyItem)) { TaschenhaendlerPlugin.ModLog.LogWarning((object)"Benutzung eines Erweiterungsitems außerhalb des Spielerinventars wurde blockiert."); return false; } if (current.AppliedCount >= current.PurchasedCount) { TaschenhaendlerPlugin.NotifyPlayer(ModLocalization.Text("Dieses Erweiterungsitem gehört nicht zum gespeicherten Kaufstand und wurde nicht verbraucht.", "This expansion item is not part of the saved purchase progress and was not consumed.")); return false; } long appliedCount = current.AppliedCount; long grantedSlots = current.GrantedSlots; Item myItem = sourceSlot.MyItem; int quantity = sourceSlot.Quantity; int count = ExtraSlots.Count; bool flag = false; try { current.AppliedCount++; checked { current.GrantedSlots += TaschenhaendlerPlugin.Instance.SlotsPerExpansion.Value; EnsureExtraSlotCount(GetDesiredExtraSlotCount(current)); } if (quantity > 1) { sourceSlot.Quantity = quantity - 1; } else { sourceSlot.MyItem = _inventory.Empty; sourceSlot.Quantity = 0; } sourceSlot.UpdateSlotImage(); CaptureOverflow(current); if (!ProgressStore.Save()) { throw new IOExceptionLikeException(); } flag = true; _inventory.UpdatePlayerInventory(); if (!SaveNativeAfterSidecarCommit()) { throw new InvalidOperationException("Erenshor hat den nativen Charakterstand nicht gespeichert."); } int value = TaschenhaendlerPlugin.Instance.SlotsPerExpansion.Value; TaschenhaendlerPlugin.NotifyPlayer(ModLocalization.Format("Inventar dauerhaft um {0} Plätze erweitert. Insgesamt: {1} Zusatzplätze.", "Inventory permanently expanded by {0} slots. Total: {1} extra slots.", value, current.GrantedSlots)); return true; } catch (Exception ex) { current.AppliedCount = appliedCount; current.GrantedSlots = grantedSlots; EnsureExtraSlotCount(count); sourceSlot.MyItem = myItem; sourceSlot.Quantity = quantity; sourceSlot.UpdateSlotImage(); CaptureOverflow(current); if (!(ex is IOExceptionLikeException)) { TaschenhaendlerPlugin.ModLog.LogError((object)$"Inventarerweiterung wurde zurückgerollt: {ex}"); TaschenhaendlerPlugin.NotifyPlayer(ModLocalization.Text("Die Inventarerweiterung ist fehlgeschlagen und wurde nicht verbraucht.", "The inventory expansion failed and was not consumed.")); } if (flag) { CaptureOverflow(current); ProgressStore.Save(); } return false; } } internal static SaveIsolationState PrepareVanillaSave() { SaveIsolationState saveIsolationState = new SaveIsolationState { CanProceed = true, Prepared = false, Extras = new List(), HiddenExpansionItems = new List() }; if ((Object)(object)_inventory == (Object)null) { return saveIsolationState; } if (ProgressStore.Current == null) { saveIsolationState.CanProceed = ExtraSlots.Count == 0; if (!saveIsolationState.CanProceed) { TaschenhaendlerPlugin.ModLog.LogError((object)"Vanilla-Speichern wurde abgebrochen, weil Zusatzslots ohne aktiven Charakterzustand vorhanden sind."); } return saveIsolationState; } if (!_sidecarAlreadyCommittedForSave) { CaptureOverflow(ProgressStore.Current); if (!ProgressStore.Save()) { saveIsolationState.CanProceed = false; return saveIsolationState; } } saveIsolationState.Prepared = true; try { saveIsolationState.Extras.AddRange(ExtraSlots.Where((ItemIcon slot) => (Object)(object)slot != (Object)null)); foreach (ItemIcon extra in saveIsolationState.Extras) { _inventory.StoredSlots.Remove(extra); } foreach (ItemIcon item in _inventory.StoredSlots.Where((ItemIcon entry) => (Object)(object)entry != (Object)null && TaschenhaendlerPlugin.IsExpansion(entry.MyItem)).ToList()) { saveIsolationState.HiddenExpansionItems.Add(new HiddenExpansionItemState { Slot = item, Item = item.MyItem, Quantity = item.Quantity }); item.MyItem = _inventory.Empty; item.Quantity = 0; item.UpdateSlotImage(); } MaskUnsafeHotkeys(saveIsolationState); RebuildAllSlots(); saveIsolationState.Prepared = saveIsolationState.Extras.Count > 0 || saveIsolationState.HiddenExpansionItems.Count > 0 || saveIsolationState.HotkeyIndices.Count > 0; return saveIsolationState; } catch (Exception arg) { saveIsolationState.CanProceed = false; TaschenhaendlerPlugin.ModLog.LogError((object)$"Vorbereitung des sicheren Vanilla-Speicherns ist fehlgeschlagen; Teilzustand wird wiederhergestellt: {arg}"); try { RestoreAfterVanillaSave(saveIsolationState); } catch (Exception arg2) { TaschenhaendlerPlugin.ModLog.LogError((object)$"Wiederherstellung nach fehlgeschlagener Save-Vorbereitung ist ebenfalls fehlgeschlagen: {arg2}"); } TaschenhaendlerPlugin.NotifyPlayer(ModLocalization.Text("Speichern wurde abgebrochen, weil die Zusatzslots nicht sicher isoliert werden konnten.", "Saving was cancelled because the extra slots could not be isolated safely.")); return saveIsolationState; } } internal static void RestoreAfterVanillaSave(SaveIsolationState state) { if (state == null || !state.Prepared || (Object)(object)_inventory == (Object)null) { return; } int num = (((Object)(object)_trashSlot != (Object)null) ? _inventory.StoredSlots.IndexOf(_trashSlot) : _inventory.StoredSlots.Count); if (num < 0) { num = _inventory.StoredSlots.Count; } foreach (ItemIcon extra in state.Extras) { if ((Object)(object)extra != (Object)null && !_inventory.StoredSlots.Contains(extra)) { _inventory.StoredSlots.Insert(num++, extra); } } foreach (HiddenExpansionItemState hiddenExpansionItem in state.HiddenExpansionItems) { if (!((Object)(object)hiddenExpansionItem?.Slot == (Object)null)) { hiddenExpansionItem.Slot.MyItem = hiddenExpansionItem.Item; hiddenExpansionItem.Slot.Quantity = hiddenExpansionItem.Quantity; hiddenExpansionItem.Slot.UpdateSlotImage(); } } RebuildAllSlots(); foreach (KeyValuePair hotkeyIndex in state.HotkeyIndices) { if ((Object)(object)hotkeyIndex.Key != (Object)null) { hotkeyIndex.Key.InvSlotIndex = hotkeyIndex.Value; } } state.Prepared = false; _scrollView?.LayoutSlots(); } internal static void CaptureOverflow(CharacterProgress progress) { if (progress == null || (Object)(object)_inventory == (Object)null) { return; } List list = new List(ExtraSlots.Count); for (int i = 0; i < ExtraSlots.Count; i++) { ItemIcon val = ExtraSlots[i]; if ((Object)(object)val == (Object)null || (Object)(object)val.MyItem == (Object)null || (Object)(object)val.MyItem == (Object)(object)_inventory.Empty) { if (UnresolvedOverflowIndices.Contains(i) && i < progress.Overflow.Count && !string.IsNullOrEmpty(progress.Overflow[i]?.Id)) { StoredItem storedItem = progress.Overflow[i]; list.Add(new StoredItem { Id = storedItem.Id, Quantity = storedItem.Quantity }); } else { list.Add(new StoredItem()); } } else { UnresolvedOverflowIndices.Remove(i); list.Add(new StoredItem { Id = (((BaseScriptableObject)val.MyItem).Id ?? string.Empty), Quantity = Math.Max(1, val.Quantity) }); } } progress.Overflow = list; CaptureExtraHotkeys(progress); } private static int GetDesiredExtraSlotCount(CharacterProgress progress) { long grantedSlots = progress.GrantedSlots; if (grantedSlots > int.MaxValue) { throw new InvalidOperationException("Die Anzahl der Zusatzplätze überschreitet die technische Listengrenze von Unity."); } return (int)grantedSlots; } private static void EnsureExtraSlotCount(int desired) { if ((Object)(object)_inventory == (Object)null) { throw new InvalidOperationException("Spielerinventar ist nicht initialisiert."); } while (ExtraSlots.Count > desired) { ItemIcon val = ExtraSlots[ExtraSlots.Count - 1]; ExtraSlots.RemoveAt(ExtraSlots.Count - 1); _inventory.StoredSlots.Remove(val); RectTransform slotRoot = GetSlotRoot(val); if ((Object)(object)slotRoot != (Object)null) { ((Component)slotRoot).gameObject.SetActive(false); Object.Destroy((Object)(object)((Component)slotRoot).gameObject); } } while (ExtraSlots.Count < desired) { AddExtraSlot(); } RebuildAllSlots(); _scrollView?.LayoutSlots(); } private static void AddExtraSlot() { RectTransform slotRoot = GetSlotRoot(((IEnumerable)_inventory.StoredSlots).FirstOrDefault((Func)delegate(ItemIcon slot) { if ((Object)(object)slot != (Object)null && !slot.TrashSlot) { RectTransform slotRoot2 = GetSlotRoot(slot); return (Object)(object)((slotRoot2 != null) ? ((Component)slotRoot2).GetComponent() : null) == (Object)null; } return false; })); if ((Object)(object)slotRoot == (Object)null) { throw new InvalidOperationException("Kein normaler Inventarslot als Vorlage gefunden."); } Transform parent = ((Transform)slotRoot).parent; RectTransform val = (RectTransform)(object)((parent is RectTransform) ? parent : null); GameObject val2 = Object.Instantiate(((Component)slotRoot).gameObject, (Transform)(object)val, false); ((Object)val2).name = $"Taschenhaendler_ExtraSlot_{ExtraSlots.Count + 1:D4}"; val2.AddComponent(); ItemIcon componentInChildren = val2.GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { Object.Destroy((Object)(object)val2); throw new InvalidOperationException("Die Slot-Vorlage enthält kein ItemIcon."); } if ((Object)(object)componentInChildren.MySparkler != (Object)null) { GameObject gameObject = ((Component)componentInChildren.MySparkler).gameObject; componentInChildren.MySparkler = null; Object.Destroy((Object)(object)gameObject); } componentInChildren.TrashSlot = false; componentInChildren.VendorSlot = false; componentInChildren.LootSlot = false; componentInChildren.BankSlot = false; componentInChildren.NotInInventory = false; componentInChildren.dragging = false; componentInChildren.assignedHotkey = null; Traverse obj = Traverse.Create((object)componentInChildren); obj.Field("hotkey").SetValue((object)null); obj.Field("MouseHomeSlot").SetValue((object)null); obj.Field("SwapWith").SetValue((object)null); obj.Field("rButton").SetValue((object)false); obj.Field("lButton").SetValue((object)false); obj.Field("doHotkey").SetValue((object)false); componentInChildren.MyItem = _inventory.Empty; componentInChildren.Quantity = 0; componentInChildren.ForceInitInv(); int num = (((Object)(object)_trashSlot != (Object)null) ? _inventory.StoredSlots.IndexOf(_trashSlot) : _inventory.StoredSlots.Count); if (num < 0) { num = _inventory.StoredSlots.Count; } _inventory.StoredSlots.Insert(num, componentInChildren); ExtraSlots.Add(componentInChildren); } private static void SetSlot(ItemIcon slot, Item item, int quantity) { slot.MyItem = item; slot.Quantity = quantity; slot.UpdateSlotImage(); } private static void RebuildAllSlots() { if (!((Object)(object)_inventory == (Object)null)) { _inventory.ALLSLOTS.Clear(); _inventory.ALLSLOTS.AddRange(_inventory.EquipmentSlots.Where((ItemIcon slot) => (Object)(object)slot != (Object)null)); _inventory.ALLSLOTS.AddRange(_inventory.StoredSlots.Where((ItemIcon slot) => (Object)(object)slot != (Object)null)); _inventory.ALLSLOTS.AddRange(_inventory.TransmogSlots.Where((ItemIcon slot) => (Object)(object)slot != (Object)null)); for (int num = 0; num < _inventory.ALLSLOTS.Count; num++) { _inventory.ALLSLOTS[num].ALLSLOTSINDEX = num; } } } private static void CaptureExtraHotkeys(CharacterProgress progress) { if (!((Object)(object)GameData.GM?.HKManager == (Object)null)) { progress.FirstExtraHotkeys = CaptureHotkeyList(GameData.GM.HKManager.FirstHotkeys); progress.SecondExtraHotkeys = CaptureHotkeyList(GameData.GM.HKManager.SecondHotkeys); } } private static List CaptureHotkeyList(List hotkeys) { List list = new List(); if (hotkeys == null) { return list; } foreach (Hotkeys hotkey in hotkeys) { int item = (((Object)(object)hotkey?.AssignedItem != (Object)null) ? ExtraSlots.IndexOf(hotkey.AssignedItem) : (-1)); list.Add(item); } return list; } private static void RestoreHotkeyList(List hotkeys, List mappings) { if (hotkeys == null || mappings == null) { return; } int num = Math.Min(hotkeys.Count, mappings.Count); for (int i = 0; i < num; i++) { int num2 = mappings[i]; if (num2 >= 0 && num2 < ExtraSlots.Count && !((Object)(object)hotkeys[i] == (Object)null) && !((Object)(object)ExtraSlots[num2] == (Object)null)) { hotkeys[i].ClearMe(); hotkeys[i].AssignItemFrominv(ExtraSlots[num2]); ExtraSlots[num2].assignedHotkey = hotkeys[i]; } } } private static void MaskUnsafeHotkeys(SaveIsolationState state) { if (GameData.GM?.HKManager?.AllHotkeys == null) { return; } foreach (Hotkeys hotkey in GameData.GM.HKManager.AllHotkeys) { if ((Object)(object)hotkey != (Object)null && (Object)(object)hotkey.AssignedItem != (Object)null && (ExtraSlots.Contains(hotkey.AssignedItem) || state.HiddenExpansionItems.Any((HiddenExpansionItemState hidden) => hidden != null && (Object)(object)hidden.Slot == (Object)(object)hotkey.AssignedItem))) { state.HotkeyIndices[hotkey] = hotkey.InvSlotIndex; hotkey.InvSlotIndex = -1; } } } private static bool IsUsableEmptyInventorySlot(ItemIcon slot) { if (IsScrollableInventorySlot(slot) && (Object)(object)slot.MyItem == (Object)(object)_inventory.Empty) { return !IsReservedUnresolvedSlot(slot); } return false; } } [HarmonyPatch(typeof(CharSelectManager), "LoadHotkeys")] internal static class ExtraHotkeyLoadPatch { [HarmonyPostfix] private static void Postfix() { InventoryExpansionController.FinishHotkeyLoad(ProgressStore.Current); } } [HarmonyPatch(typeof(Inventory), "Start")] internal static class InventoryStartPatch { [HarmonyPostfix] [HarmonyPriority(0)] private static void Postfix(Inventory __instance) { try { InventoryExpansionController.Initialize(__instance); } catch (Exception arg) { TaschenhaendlerPlugin.ModLog.LogError((object)$"Inventarinitialisierung fehlgeschlagen: {arg}"); } } } [HarmonyPatch(typeof(CharSelectManager), "LoadEquipment")] internal static class CharacterLoadPatch { [HarmonyPrefix] private static void Prefix() { InventoryExpansionController.LoadCharacter(ProgressStore.SelectCurrentCharacter()); } [HarmonyPostfix] private static void Postfix() { InventoryExpansionController.FinishCharacterLoad(ProgressStore.Current); } } [HarmonyPatch(typeof(CharSelectManager), "SelectSlot")] internal static class CharacterSelectionPatch { [HarmonyPrefix] private static bool Prefix() { return InventoryExpansionController.CaptureCurrentBeforeCharacterSwitch(); } [HarmonyPostfix] private static void Postfix() { if (GameData.CurrentCharacterSlot != null && string.IsNullOrEmpty(GameData.CurrentCharacterSlot.CharName)) { InventoryExpansionController.ClearLoadedCharacter(); ProgressStore.ClearCurrent(); } } } [HarmonyPatch(typeof(CharSelectManager), "SelectBackupSlot")] internal static class BackupCharacterSelectionPatch { [HarmonyPrefix] private static bool Prefix() { return InventoryExpansionController.CaptureCurrentBeforeCharacterSwitch(); } } [HarmonyPatch(typeof(ItemIcon), "UseConsumable")] internal static class UseExpansionPatch { [HarmonyPrefix] private static bool Prefix(ItemIcon __instance) { if (!TaschenhaendlerPlugin.IsExpansion(__instance?.MyItem)) { return true; } InventoryExpansionController.TryUseExpansion(__instance); return false; } } [HarmonyPatch(typeof(GameManager), "SaveGameData")] internal static class SafeInventorySavePatch { [HarmonyPrefix] private static bool Prefix(out SaveIsolationState __state) { __state = InventoryExpansionController.PrepareVanillaSave(); return __state.CanProceed; } [HarmonyPostfix] private static void Postfix(SaveIsolationState __state) { InventoryExpansionController.RestoreAfterVanillaSave(__state); } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception, SaveIsolationState __state) { InventoryExpansionController.RestoreAfterVanillaSave(__state); return __exception; } } [HarmonyPatch(typeof(GameData), "SaveData")] internal static class NativeCharacterSaveResultPatch { [HarmonyPostfix] private static void Postfix(bool __result) { InventoryExpansionController.ReportNativeSaveResult(__result); } } internal sealed class DeletedCharacterKey { internal int SlotIndex; internal string Name; } [HarmonyPatch(typeof(CharSelectManager), "EraseCharacter")] internal static class CharacterErasePatch { [HarmonyPrefix] private static void Prefix(CharSelectManager __instance, out DeletedCharacterKey __state) { __state = null; SaveGameData val = GameData.CurrentCharacterSlot; if (val == null) { int value = Traverse.Create((object)__instance).Field("curIndex").GetValue(); if (GameData.SaveSlots != null && value >= 0 && value < GameData.SaveSlots.Count) { val = GameData.SaveSlots[value]; } } if (val != null) { __state = new DeletedCharacterKey { SlotIndex = val.index, Name = (val.CharName ?? string.Empty) }; } } [HarmonyPostfix] private static void Postfix(DeletedCharacterKey __state) { if (__state != null) { InventoryExpansionController.ClearLoadedCharacter(); ProgressStore.Remove(__state.SlotIndex, __state.Name); } } } internal enum InventoryFilterMode { All, Weapons, ArmorAndJewelry, Consumables, Crafting, QuestAndBooks, Rare, Other } internal enum InventorySortMode { Name, Type, Level, Value, Quantity } internal static class InventoryToolsState { private static readonly string[] StableSortModes = new string[5] { "Name", "Type", "Level", "Value", "Quantity" }; private static string _searchText = string.Empty; private static InventoryFilterMode _filter = InventoryFilterMode.All; internal static string SearchText => _searchText; internal static InventoryFilterMode Filter => _filter; internal static InventorySortMode PendingSortMode { get { if (!TryParseSortMode(TaschenhaendlerPlugin.Instance?.PreferredSortMode?.Value, out var mode)) { return InventorySortMode.Type; } return mode; } } internal static bool PendingDescending => TaschenhaendlerPlugin.Instance?.SortDescending?.Value == true; internal static IReadOnlyList FilterLabels { get { if (ModLocalization.IsGerman) { return new string[8] { "Alle", "Waffen", "Rüst./Schm.", "Verbrauch", "Handwerk", "Quest/Buch", "Selten", "Sonstiges" }; } return new string[8] { "All", "Weapons", "Armor/Jewel.", "Consume", "Crafting", "Quest/Book", "Rare", "Other" }; } } internal static IReadOnlyList SortLabels { get { if (ModLocalization.IsGerman) { return new string[5] { "Name", "Typ", "Stufe", "Wert", "Menge" }; } return new string[5] { "Name", "Type", "Level", "Value", "Quantity" }; } } internal static void SetSearch(string value) { _searchText = value?.Trim() ?? string.Empty; } internal static void SetFilter(int index) { _filter = (InventoryFilterMode)Mathf.Clamp(index, 0, Enum.GetValues(typeof(InventoryFilterMode)).Length - 1); } internal static void SetPendingSortMode(int index) { index = Mathf.Clamp(index, 0, StableSortModes.Length - 1); if (TaschenhaendlerPlugin.Instance?.PreferredSortMode != null) { TaschenhaendlerPlugin.Instance.PreferredSortMode.Value = StableSortModes[index]; } } internal static void TogglePendingDirection() { if (TaschenhaendlerPlugin.Instance?.SortDescending != null) { TaschenhaendlerPlugin.Instance.SortDescending.Value = !TaschenhaendlerPlugin.Instance.SortDescending.Value; } } internal static bool TryParseSortMode(string value, out InventorySortMode mode) { for (int i = 0; i < StableSortModes.Length; i++) { if (string.Equals(value, StableSortModes[i], StringComparison.OrdinalIgnoreCase)) { mode = (InventorySortMode)i; return true; } } mode = InventorySortMode.Type; return false; } internal static List GetDisplayedSlots(IEnumerable source, Item empty) { return (from slot in source where (Object)(object)slot != (Object)null && !slot.TrashSlot where Matches(slot, empty) select slot).ToList(); } private static bool Matches(ItemIcon slot, Item empty) { Item val = slot?.MyItem; if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)empty) { if (_filter == InventoryFilterMode.All) { return string.IsNullOrEmpty(_searchText); } return false; } if (!string.IsNullOrEmpty(_searchText)) { bool num = (val.ItemName ?? string.Empty).IndexOf(_searchText, StringComparison.CurrentCultureIgnoreCase) >= 0; bool flag = (val.Lore ?? string.Empty).IndexOf(_searchText, StringComparison.CurrentCultureIgnoreCase) >= 0; if (!num && !flag) { return false; } } if (_filter != InventoryFilterMode.All && GetFilterCategory(val) != _filter) { if (_filter == InventoryFilterMode.Rare) { if (!val.RareItem && !val.Relic) { return val.Unique; } return true; } return false; } return true; } private static InventoryFilterMode GetFilterCategory(Item item) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Invalid comparison between Unknown and I4 //IL_0032: 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) if ((Object)(object)item == (Object)null) { return InventoryFilterMode.Other; } if ((int)item.RequiredSlot == 13 || (int)item.RequiredSlot == 14 || (int)item.RequiredSlot == 15 || item.WeaponDmg != 0 || (int)item.ThisWeaponType != 0 || item.IsBow || item.IsWand) { return InventoryFilterMode.Weapons; } if ((int)item.RequiredSlot != 0) { return InventoryFilterMode.ArmorAndJewelry; } if ((Object)(object)item.AssignQuestOnRead != (Object)null || (Object)(object)item.CompleteOnRead != (Object)null || !string.IsNullOrWhiteSpace(item.BookTitle) || (Object)(object)item.TeachSpell != (Object)null || (Object)(object)item.TeachSkill != (Object)null) { return InventoryFilterMode.QuestAndBooks; } if ((Object)(object)item.ItemEffectOnClick != (Object)null || (Object)(object)item.ItemSkillUse != (Object)null || item.Disposable) { return InventoryFilterMode.Consumables; } if (item.Template || item.FuelSource || item.Mining > 0 || item.FurnitureSet) { return InventoryFilterMode.Crafting; } return InventoryFilterMode.Other; } } internal sealed class InventoryToolsPanel : MonoBehaviour { private static readonly HashSet LivePanels = new HashSet(); private Inventory _inventory; private InventoryScrollView _scrollView; private TMP_InputField _search; private TextMeshProUGUI _searchPlaceholder; private InventoryChoiceDropdown _language; private InventoryChoiceDropdown _filter; private InventoryChoiceDropdown _sortMode; private Button _directionButton; private TextMeshProUGUI _directionText; private Button _sortButton; private TextMeshProUGUI _sortButtonText; private TMP_FontAsset _font; private float _autoSortGuard; internal static InventoryToolsPanel Create(Inventory inventory, InventoryScrollView scrollView, RectTransform parent, Vector2 anchorMin, Vector2 anchorMax, Vector2 anchoredPosition, Vector2 size) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_0141: Unknown result type (might be due to invalid IL or missing references) InventoryToolsPanel componentInChildren = ((Component)parent).GetComponentInChildren(true); if ((Object)(object)componentInChildren != (Object)null) { componentInChildren._inventory = inventory; componentInChildren._scrollView = scrollView; componentInChildren.RefreshLocalization(); return componentInChildren; } GameObject val = new GameObject("CBra_InventoryTools", new Type[4] { typeof(RectTransform), typeof(Image), typeof(Outline), typeof(InventoryToolsPanel) }); RectTransform component = val.GetComponent(); ((Transform)component).SetParent((Transform)(object)parent, false); component.anchorMin = anchorMin; component.anchorMax = anchorMax; component.pivot = new Vector2(0.5f, 0.5f); component.anchoredPosition = anchoredPosition; component.sizeDelta = size; ((Graphic)val.GetComponent()).color = new Color(0.035f, 0.12f, 0.16f, 0.94f); Outline component2 = val.GetComponent(); ((Shadow)component2).effectColor = new Color(0.35f, 0.75f, 0.78f, 0.9f); ((Shadow)component2).effectDistance = new Vector2(1f, -1f); InventoryToolsPanel component3 = val.GetComponent(); component3._inventory = inventory; component3._scrollView = scrollView; component3._font = (((Object)(object)inventory.GoldTXT != (Object)null) ? ((TMP_Text)inventory.GoldTXT).font : null); component3.Build(size); component3.RefreshLocalization(); ((Transform)component).SetAsLastSibling(); component3.DisableExternalAutoSortButtons(); return component3; } internal static void RefreshAllLocalization() { InventoryToolsPanel[] array = LivePanels.Where((InventoryToolsPanel panel) => (Object)(object)panel != (Object)null).ToArray(); for (int num = 0; num < array.Length; num++) { array[num].RefreshLocalization(); } } private void OnEnable() { LivePanels.Add(this); } private void OnDisable() { if ((Object)(object)_search != (Object)null && _search.isFocused) { GameData.PlayerTyping = false; } } private void OnDestroy() { LivePanels.Remove(this); if ((Object)(object)_search != (Object)null && _search.isFocused) { GameData.PlayerTyping = false; } } private void Update() { _autoSortGuard -= Time.unscaledDeltaTime; if (_autoSortGuard <= 0f) { _autoSortGuard = 2f; DisableExternalAutoSortButtons(); } } private void Build(Vector2 size) { //IL_0011: 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_003b: 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_0087: 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_00bc: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0155: 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) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_01af: 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_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown Transform transform = ((Component)this).transform; RectTransform parent = (RectTransform)(object)((transform is RectTransform) ? transform : null); float num = Math.Max(1f, size.x - 8f); _search = CreateSearch(parent, new Vector2(0f, 31f), new Vector2(num, 23f)); float num2 = Math.Min(82f, num * 0.43f); float num3 = num - num2 - 4f; _language = InventoryChoiceDropdown.Create(parent, "CBra_LanguageDropdown", new Vector2((0f - (num - num2)) * 0.5f, 3f), new Vector2(num2, 23f), _font); _filter = InventoryChoiceDropdown.Create(parent, "CBra_FilterDropdown", new Vector2((num - num3) * 0.5f, 3f), new Vector2(num3, 23f), _font); float num4 = 28f; float num5 = 52f; float num6 = 6f; float num7 = num - num4 - num5 - num6; float num8 = (0f - num) * 0.5f; _sortMode = InventoryChoiceDropdown.Create(parent, "CBra_SortModeDropdown", new Vector2(num8 + num7 * 0.5f, -25f), new Vector2(num7, 23f), _font); _directionButton = CreateButton(parent, "CBra_SortDirection", new Vector2(num8 + num7 + 3f + num4 * 0.5f, -25f), new Vector2(num4, 23f), out _directionText); ((UnityEvent)_directionButton.onClick).AddListener((UnityAction)delegate { InventoryToolsState.TogglePendingDirection(); RefreshLocalization(); }); _sortButton = CreateButton(parent, "CBra_SortButton", new Vector2(num * 0.5f - num5 * 0.5f, -25f), new Vector2(num5, 23f), out _sortButtonText); ((UnityEvent)_sortButton.onClick).AddListener(new UnityAction(SortNow)); _language.SetSelectionHandler(delegate(int index) { ModLocalization.SetModeByIndex(index); }); _filter.SetSelectionHandler(delegate(int index) { InventoryToolsState.SetFilter(index); _scrollView?.LayoutSlots(resetScroll: true); RefreshLocalization(); }); _sortMode.SetSelectionHandler(delegate(int index) { InventoryToolsState.SetPendingSortMode(index); RefreshLocalization(); }); } private TMP_InputField CreateSearch(RectTransform parent, Vector2 position, Vector2 size) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_00ba: 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_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_0199: 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_0208: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021d: Expected O, but got Unknown //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Expected O, but got Unknown //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Expected O, but got Unknown GameObject val = new GameObject("CBra_InventorySearch", new Type[2] { typeof(RectTransform), typeof(Image) }); RectTransform component = val.GetComponent(); ConfigureRect(component, parent, position, size); Image component2 = val.GetComponent(); ((Graphic)component2).color = new Color(0.015f, 0.035f, 0.045f, 0.96f); RectTransform component3 = new GameObject("Text Area", new Type[2] { typeof(RectTransform), typeof(RectMask2D) }).GetComponent(); ((Transform)component3).SetParent((Transform)(object)component, false); component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.offsetMin = new Vector2(7f, 1f); component3.offsetMax = new Vector2(-7f, -1f); TextMeshProUGUI val2 = CreateText(component3, "Text", string.Empty, 13f, (TextAlignmentOptions)4097); RectTransform rectTransform = ((TMP_Text)val2).rectTransform; rectTransform.anchorMin = Vector2.zero; rectTransform.anchorMax = Vector2.one; rectTransform.offsetMin = Vector2.zero; rectTransform.offsetMax = Vector2.zero; _searchPlaceholder = CreateText(component3, "Placeholder", string.Empty, 13f, (TextAlignmentOptions)4097); ((Graphic)_searchPlaceholder).color = new Color(0.72f, 0.78f, 0.8f, 0.72f); RectTransform rectTransform2 = ((TMP_Text)_searchPlaceholder).rectTransform; rectTransform2.anchorMin = Vector2.zero; rectTransform2.anchorMax = Vector2.one; rectTransform2.offsetMin = Vector2.zero; rectTransform2.offsetMax = Vector2.zero; TMP_InputField obj = val.AddComponent(); obj.textViewport = component3; obj.textComponent = (TMP_Text)(object)val2; obj.placeholder = (Graphic)(object)_searchPlaceholder; ((Selectable)obj).targetGraphic = (Graphic)(object)component2; obj.lineType = (LineType)0; obj.contentType = (ContentType)0; obj.characterLimit = 80; obj.customCaretColor = true; obj.caretColor = Color.white; obj.selectionColor = new Color(0.25f, 0.7f, 0.8f, 0.45f); obj.onValueChanged = new OnChangeEvent(); obj.onSelect = new SelectionEvent(); obj.onDeselect = new SelectionEvent(); ((UnityEvent)(object)obj.onValueChanged).AddListener((UnityAction)delegate(string value) { InventoryToolsState.SetSearch(value); _scrollView?.LayoutSlots(resetScroll: true); }); ((UnityEvent)(object)obj.onSelect).AddListener((UnityAction)delegate { GameData.PlayerTyping = true; }); ((UnityEvent)(object)obj.onDeselect).AddListener((UnityAction)delegate { GameData.PlayerTyping = false; }); obj.SetTextWithoutNotify(InventoryToolsState.SearchText); return obj; } private Button CreateButton(RectTransform parent, string name, Vector2 position, Vector2 size, out TextMeshProUGUI label) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0044: 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_0077: 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_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(Image), typeof(Button) }); RectTransform component = val.GetComponent(); ConfigureRect(component, parent, position, size); Image component2 = val.GetComponent(); ((Graphic)component2).color = new Color(0.08f, 0.26f, 0.31f, 0.98f); Button component3 = val.GetComponent