

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.Json;
using HarmonyLib;
using Il2CppFishNet;
using Il2CppFishNet.Connection;
using Il2CppFishNet.Object;
using Il2CppInterop.Runtime;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppNewtonsoft.Json;
using Il2CppScheduleOne;
using Il2CppScheduleOne.AvatarFramework;
using Il2CppScheduleOne.AvatarFramework.Customization;
using Il2CppScheduleOne.Core.Items.Framework;
using Il2CppScheduleOne.DevUtilities;
using Il2CppScheduleOne.Equipping;
using Il2CppScheduleOne.ItemFramework;
using Il2CppScheduleOne.Levelling;
using Il2CppScheduleOne.NPCs;
using Il2CppScheduleOne.NPCs.Behaviour;
using Il2CppScheduleOne.Networking;
using Il2CppScheduleOne.Persistence;
using Il2CppScheduleOne.Persistence.Datas;
using Il2CppScheduleOne.Persistence.Loaders;
using Il2CppScheduleOne.PlayerScripts;
using Il2CppScheduleOne.Product;
using Il2CppScheduleOne.Product.Packaging;
using Il2CppScheduleOne.Storage;
using Il2CppScheduleOne.TV;
using Il2CppScheduleOne.Tools;
using Il2CppScheduleOne.UI;
using Il2CppScheduleOne.UI.ATM;
using Il2CppScheduleOne.UI.Handover;
using Il2CppScheduleOne.UI.Items;
using Il2CppScheduleOne.UI.Phone;
using Il2CppScheduleOne.UI.Shop;
using Il2CppScheduleOne.UI.Stations;
using Il2CppScheduleOne.Variables;
using Il2CppScheduleOne.Vehicles;
using Il2CppSteamworks;
using Il2CppSystem;
using Il2CppSystem.Collections;
using Il2CppSystem.Collections.Generic;
using Il2CppSystem.Linq;
using Il2CppTMPro;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using PackRat;
using PackRat.Config;
using PackRat.Extensions;
using PackRat.Helpers;
using PackRat.Networking;
using PackRat.Patches;
using PackRat.Shops;
using PackRat.Storage;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(global::PackRat.PackRat), "PackRat", "1.1", "SirTidez", null)]
[assembly: MelonColor(1, 255, 165, 0)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("PackRat-IL2CPP")]
[assembly: AssemblyConfiguration("Debug IL2CPP")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+af91a4e56e731163b437474798bf5deef32360bd")]
[assembly: AssemblyProduct("PackRat-IL2CPP")]
[assembly: AssemblyTitle("PackRat-IL2CPP")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 PackRat
{
public static class BuildInfo
{
public const string Name = "PackRat";
public const string Description = "Portable backpack storage for Schedule One";
public const string Author = "SirTidez";
public const string Version = "1.1";
}
public class PackRat : MelonMod
{
public override void OnInitializeMelon()
{
Configuration.Instance.Load();
ModLogger.Info("PackRat initialized.");
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
Configuration.Instance.Reset();
if (!(sceneName != "Main"))
{
ConfigSyncManager.StartSync();
BackpackShopIntegration.RunWhenReady();
}
}
}
[RegisterTypeInIl2Cpp]
public class PlayerBackpack : MonoBehaviour
{
[CompilerGenerated]
private sealed class <DeferredConfigureStorage>d__33 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public PlayerBackpack instance;
public int slotCount;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DeferredConfigureStorage>d__33(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = null;
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if ((Object)(object)instance == (Object)null || (Object)(object)instance._storage == (Object)null)
{
return false;
}
instance.UpdateSize(slotCount);
instance.OnStartClient(isOwner: true);
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public const string StorageName = "Backpack";
public const int MaxStorageSlots = 40;
private bool _backpackEnabled = true;
private StorageEntity _storage;
private int _lastTierIndex = -2;
private string _openTitle;
private int _equippedTierIndex = -1;
private const int TierCheckIntervalFrames = 60;
public static PlayerBackpack Instance { get; private set; }
public int EquippedTierIndex => _equippedTierIndex;
public int HighestPurchasedTierIndex => EquippedTierIndex;
public int CurrentTierIndex
{
get
{
Configuration instance = Configuration.Instance;
if (_equippedTierIndex < 0)
{
return -1;
}
for (int num = _equippedTierIndex; num >= 0; num--)
{
if (num < instance.TierEnabled.Length && instance.TierEnabled[num])
{
return num;
}
}
return -1;
}
}
public BackpackTierDefinition CurrentTier
{
get
{
int currentTierIndex = CurrentTierIndex;
return (currentTierIndex >= 0) ? Configuration.BackpackTiers[currentTierIndex] : null;
}
}
public bool IsUnlocked => CurrentTierIndex >= 0;
public bool IsPoliceSearchable => CurrentTierIndex >= 2;
public bool IsOpen => Singleton<StorageMenu>.Instance.IsOpen && ((TMP_Text)Singleton<StorageMenu>.Instance.TitleLabel).text == _openTitle;
public List<ItemSlot> ItemSlots => Enumerable.ToList<ItemSlot>(((Il2CppObjectBase)_storage.ItemSlots).Cast<IEnumerable<ItemSlot>>());
public PlayerBackpack(IntPtr ptr)
: base(ptr)
{
}
public void SetEquippedTierIndex(int tierIndex)
{
_equippedTierIndex = ((tierIndex < 0) ? (-1) : Math.Min(tierIndex, Configuration.BackpackTiers.Length - 1));
}
public void SetHighestPurchasedTierIndex(int tierIndex)
{
SetEquippedTierIndex(tierIndex);
}
public void RestorePurchasedTier(int tierIndex)
{
SetEquippedTierIndex(tierIndex);
EnsureCorrectTierApplied();
}
private void Awake()
{
_storage = ((Component)this).gameObject.GetComponentInParent<StorageEntity>();
if ((Object)(object)_storage == (Object)null)
{
ModLogger.Error("Player does not have a BackpackStorage component!");
return;
}
ModLogger.Info("Configuring backpack storage...");
int currentTierIndex = CurrentTierIndex;
int slotCount = ((currentTierIndex >= 0) ? Configuration.Instance.TierSlotCounts[currentTierIndex] : Configuration.BackpackTiers[0].DefaultSlotCount);
MelonCoroutines.Start(DeferredConfigureStorage(this, slotCount));
}
[IteratorStateMachine(typeof(<DeferredConfigureStorage>d__33))]
private static IEnumerator DeferredConfigureStorage(PlayerBackpack instance, int slotCount)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DeferredConfigureStorage>d__33(0)
{
instance = instance,
slotCount = slotCount
};
}
private void Update()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
bool keyDown = Input.GetKeyDown(Configuration.Instance.ToggleKey);
if (keyDown || Time.frameCount % 60 == 0)
{
int currentTierIndex = CurrentTierIndex;
if (currentTierIndex != _lastTierIndex)
{
_lastTierIndex = currentTierIndex;
ApplyCurrentTier(currentTierIndex);
}
}
if (!_backpackEnabled || !keyDown)
{
return;
}
try
{
if (TryConsumeSelectedHotbarBackpackItem(out var appliedTier))
{
if (appliedTier >= 0)
{
ModLogger.Info($"Backpack tier {appliedTier} ({Configuration.BackpackTiers[appliedTier].Name}) applied; opening backpack.");
}
if (IsOpen)
{
Close();
}
else
{
Open();
}
}
else if (IsUnlocked)
{
if (IsOpen)
{
Close();
}
else
{
Open();
}
}
}
catch (Exception exception)
{
ModLogger.Error("Error toggling backpack", exception);
}
}
private bool TryConsumeSelectedHotbarBackpackItem(out int appliedTier)
{
appliedTier = -1;
try
{
PlayerInventory instance = PlayerSingleton<PlayerInventory>.Instance;
if ((Object)(object)instance == (Object)null)
{
return false;
}
object obj = ReflectionUtils.TryGetFieldOrProperty(instance, "hotbarSlots");
if (obj == null)
{
return false;
}
int num = ReflectionUtils.TryGetListCount(obj);
if (num <= 0)
{
return false;
}
int selectedHotbarIndex = GetSelectedHotbarIndex(instance);
if (selectedHotbarIndex >= 0 && selectedHotbarIndex < num && TryConsumeBackpackItemFromSlot(instance, obj, selectedHotbarIndex, out appliedTier))
{
return true;
}
for (int i = 0; i < num; i++)
{
if (TryConsumeBackpackItemFromSlot(instance, obj, i, out appliedTier))
{
return true;
}
}
List<object> list = ReflectionUtils.TryGetAllListLikeMembers(instance);
foreach (object item in list)
{
if (item == obj)
{
continue;
}
int num2 = ReflectionUtils.TryGetListCount(item);
for (int j = 0; j < num2; j++)
{
if (TryConsumeBackpackItemFromSlot(instance, item, j, out appliedTier))
{
return true;
}
}
}
return false;
}
catch (Exception exception)
{
ModLogger.Error("TryConsumeSelectedHotbarBackpackItem", exception);
return false;
}
}
private bool TryConsumeBackpackItemFromSlot(object playerInventory, object slotsList, int index, out int appliedTier)
{
appliedTier = -1;
object obj = ReflectionUtils.TryGetListItem(slotsList, index);
if (obj == null)
{
return false;
}
object obj2 = ReflectionUtils.TryGetFieldOrProperty(obj, "ItemInstance");
if (obj2 == null)
{
return false;
}
object obj3 = ReflectionUtils.TryGetFieldOrProperty(obj2, "Definition");
if (obj3 == null)
{
return false;
}
object obj4 = ReflectionUtils.TryGetFieldOrProperty(obj3, "ID") ?? ReflectionUtils.TryGetFieldOrProperty(obj3, "id");
string text = (obj4 as string) ?? obj4?.ToString();
if (string.IsNullOrEmpty(text) || !text.StartsWith("PackRat_Backpack_Tier_", StringComparison.Ordinal))
{
return false;
}
if (!BackpackShopIntegration.IsBackpackTierPurchase(text, out var tierIndex) || tierIndex < 0)
{
return false;
}
ClearSlotItem(obj);
RefreshInventoryUIAfterSlotChange(playerInventory, obj);
if (tierIndex != _equippedTierIndex)
{
SetEquippedTierIndex(tierIndex);
ApplyTierAfterPurchase(tierIndex);
BackpackShopIntegration.RefreshBackpackListingsInAllShops();
appliedTier = tierIndex;
}
return true;
}
private static int GetSelectedHotbarIndex(object playerInventory)
{
if (playerInventory == null)
{
return -1;
}
string[] array = new string[16]
{
"selectedSlotIndex", "SelectedSlotIndex", "selectedIndex", "SelectedIndex", "currentSlotIndex", "CurrentSlotIndex", "activeSlotIndex", "ActiveSlotIndex", "activeIndex", "ActiveIndex",
"equippedSlotIndex", "EquippedSlotIndex", "SelectedSlot", "selectedSlot", "slotIndex", "SlotIndex"
};
foreach (string memberName in array)
{
object obj = ReflectionUtils.TryGetFieldOrProperty(playerInventory, memberName);
if (obj != null)
{
if (obj is int num && num >= 0)
{
return num;
}
if (obj is byte result)
{
return result;
}
if (obj is short num2 && num2 >= 0)
{
return num2;
}
if (obj is long num3 && num3 >= 0 && num3 <= int.MaxValue)
{
return (int)num3;
}
}
}
return -1;
}
private static void ClearSlotItem(object slot)
{
if (slot == null)
{
return;
}
Type type = slot.GetType();
MethodInfo methodInfo = ReflectionUtils.GetMethod(type, "ClearStoredInstance", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? ReflectionUtils.GetMethod(type, "Clear", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? ReflectionUtils.GetMethod(type, "ClearSlot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (methodInfo != null)
{
try
{
methodInfo.Invoke(slot, null);
return;
}
catch
{
}
}
ReflectionUtils.TrySetFieldOrProperty(slot, "ItemInstance", null);
}
private static void RefreshInventoryUIAfterSlotChange(object playerInventory, object slotThatChanged)
{
if (slotThatChanged != null)
{
ReflectionUtils.TryInvokeParameterlessCallback(slotThatChanged, "onItemDataChanged", "OnItemDataChanged", "ItemDataChanged");
}
if (playerInventory != null)
{
ReflectionUtils.TryInvokeParameterlessCallback(playerInventory, "Refresh", "RefreshUI", "UpdateDisplay", "OnInventoryChanged", "NotifySlotsChanged", "Rebuild");
}
}
private void ApplyCurrentTier(int tierIdx)
{
if (tierIdx >= 0)
{
int num = Configuration.Instance.TierSlotCounts[tierIdx];
if (_storage.SlotCount != num)
{
ModLogger.Info($"Backpack upgraded to {Configuration.BackpackTiers[tierIdx].Name} ({num} slots).");
UpdateSize(num);
}
}
}
public void ApplyTierAfterPurchase(int tierIdx)
{
if (tierIdx >= 0)
{
_lastTierIndex = tierIdx;
ApplyCurrentTier(tierIdx);
}
}
public void EnsureCorrectTierApplied()
{
_lastTierIndex = CurrentTierIndex;
if (!((Object)(object)_storage == (Object)null) && _lastTierIndex >= 0)
{
ApplyCurrentTier(_lastTierIndex);
}
}
public void SetBackpackEnabled(bool state)
{
if (!state)
{
Close();
}
_backpackEnabled = state;
}
public void Open()
{
if (!_backpackEnabled)
{
ModLogger.Debug("Backpack open blocked: backpack disabled.");
}
else if (!IsUnlocked)
{
ModLogger.Debug($"Backpack open blocked: not unlocked (CurrentTierIndex={CurrentTierIndex}, EquippedTier={_equippedTierIndex}). Purchase a tier at the Hardware Store.");
}
else if ((Object)(object)_storage == (Object)null)
{
ModLogger.Warn("Backpack open blocked: no storage entity.");
}
else if (!Singleton<ManagementClipboard>.Instance.IsEquipped && !Singleton<StorageMenu>.Instance.IsOpen && !PlayerSingleton<Phone>.Instance.IsOpen)
{
if (CameraLockedStateHelper.IsCameraLockedByUI())
{
ModLogger.Debug("Backpack blocked: player is in camera-locked UI (TV, ATM, dialogue, vehicle, etc.).");
return;
}
_openTitle = CurrentTier?.Name ?? "Backpack";
StorageMenu instance = Singleton<StorageMenu>.Instance;
instance.SlotGridLayout.constraintCount = _storage.DisplayRowCount;
instance.Open(_openTitle, string.Empty, ((Il2CppObjectBase)_storage).Cast<IItemSlotOwner>());
_storage.SendAccessor(((NetworkBehaviour)Player.Local).NetworkObject);
}
}
public void Close()
{
if (_backpackEnabled && IsOpen)
{
Singleton<StorageMenu>.Instance.CloseMenu();
_storage.SendAccessor((NetworkObject)null);
}
}
public bool ContainsItemsOfInterest(EStealthLevel maxStealthLevel)
{
//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < _storage.ItemSlots.Count; i++)
{
List<ItemSlot> itemSlots = _storage.ItemSlots;
ItemSlot val = ((Il2CppObjectBase)itemSlots[new Index(i).GetOffset(itemSlots.Count)]).Cast<ItemSlot>();
if (((val != null) ? val.ItemInstance : null) == null)
{
continue;
}
ItemInstance itemInstance = val.ItemInstance;
ProductItemInstance val2 = (ProductItemInstance)(object)((itemInstance is ProductItemInstance) ? itemInstance : null);
if (val2 == null)
{
string a = (ReflectionUtils.TryGetFieldOrProperty(val.ItemInstance.Definition, "legalStatus") ?? ReflectionUtils.TryGetFieldOrProperty(val.ItemInstance.Definition, "LegalStatus"))?.ToString();
if (!string.Equals(a, "Legal", StringComparison.Ordinal))
{
return true;
}
}
else if ((Object)(object)val2.AppliedPackaging == (Object)null || val2.AppliedPackaging.StealthLevel <= maxStealthLevel)
{
return true;
}
}
return false;
}
public void Upgrade(int slotCount)
{
if ((slotCount >= 1 && slotCount <= 40) || 1 == 0)
{
int num = _storage.SlotCount + slotCount;
if (num > 40)
{
ModLogger.Warn($"Cannot upgrade backpack to more than {40} slots.");
}
else
{
UpdateSize(num);
}
}
}
public void Downgrade(int slotCount, bool force = false)
{
if (slotCount < 1)
{
return;
}
if (!force && slotCount >= _storage.SlotCount)
{
ModLogger.Warn("Cannot downgrade backpack to zero slots. A minimum of one must remain.");
return;
}
int num = _storage.SlotCount - slotCount;
if (num < 1)
{
num = 1;
}
if (force)
{
UpdateSize(num);
return;
}
bool flag = true;
List<ItemSlot> range = _storage.ItemSlots.GetRange(num, _storage.SlotCount - num);
for (int i = 0; i < range.Count; i++)
{
List<ItemSlot> val = range;
ItemSlot val2 = ((Il2CppObjectBase)val[new Index(i).GetOffset(val.Count)]).Cast<ItemSlot>();
if (((val2 != null) ? val2.ItemInstance : null) != null)
{
ModLogger.Warn("Downgrading backpack will remove item: " + ((Object)val2.ItemInstance.Definition).name);
flag = false;
}
}
if (!flag)
{
ModLogger.Warn("Cannot downgrade backpack due to items present in removed slots.");
}
else
{
UpdateSize(num);
}
}
private void UpdateSize(int newSize)
{
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00cf: Expected O, but got Unknown
_storage.SlotCount = newSize;
StorageEntity storage = _storage;
if (1 == 0)
{
}
int displayRowCount = ((newSize <= 20) ? ((int)Math.Ceiling((double)newSize / 5.0)) : ((newSize > 80) ? ((int)Math.Ceiling((double)newSize / 16.0)) : ((int)Math.Ceiling((double)newSize / 10.0))));
if (1 == 0)
{
}
storage.DisplayRowCount = displayRowCount;
if (_storage.ItemSlots.Count > newSize)
{
_storage.ItemSlots.RemoveRange(newSize, _storage.ItemSlots.Count - newSize);
return;
}
for (int i = _storage.ItemSlots.Count; i < newSize; i++)
{
ItemSlot val = new ItemSlot();
int count = _storage.ItemSlots.Count;
if ((Delegate)(object)val.onItemDataChanged == (Delegate)null)
{
val.onItemDataChanged = Action.op_Implicit((Action)_storage.ContentsChanged);
}
else
{
((Delegate)val.onItemDataChanged).CombineImpl((Delegate)(object)Action.op_Implicit((Action)_storage.ContentsChanged));
}
val.SetSlotOwner(((Il2CppObjectBase)_storage).Cast<IItemSlotOwner>());
if (_storage.ItemSlots.Count == count)
{
_storage.ItemSlots.Add(val);
}
}
}
private void OnStartClient(bool isOwner)
{
if (!isOwner)
{
ModLogger.Info("Destroying non-local player backpack on: " + ((Object)this).name);
Object.Destroy((Object)(object)this);
}
else if ((Object)(object)Instance != (Object)null)
{
ModLogger.Warn("Multiple instances of " + ((Object)this).name + " exist. Keeping prior instance reference.");
Object.Destroy((Object)(object)this);
}
else
{
Instance = this;
CameraLockedStateHelper.PrewarmCache();
}
}
private void OnDestroy()
{
if ((Object)(object)Instance == (Object)(object)this)
{
Instance = null;
}
}
}
}
namespace PackRat.Storage
{
public sealed class BackpackSaveData
{
public string Contents { get; set; }
public int EquippedTierIndex { get; set; } = -1;
public int HighestPurchasedTierIndex { get; set; } = -1;
}
}
namespace PackRat.Shops
{
public static class BackpackShopIntegration
{
[CompilerGenerated]
private sealed class <WaitAndIntegrate>d__10 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
private int <i>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <WaitAndIntegrate>d__10(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<i>5__1 = 0;
break;
case 1:
<>1__state = -1;
AddToAllHardwareStoresInScene();
<i>5__1++;
break;
}
if (<i>5__1 < 60)
{
<>2__current = (object)new WaitForSeconds(0.5f);
<>1__state = 1;
return true;
}
if (_shopsIntegrated.Count == 0)
{
LogHardwareStoreNotFound();
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public const string BackpackItemIdPrefix = "PackRat_Backpack_Tier_";
private const string HardwareStoreName = "Hardware Store";
private static readonly string[] TierDescriptions = new string[5] { "A basic 8-slot backpack. Good for starting out.", "A compact 16-slot pack. Stays under the radar.", "24 slots. Police may search this size and above.", "32 slots. Sturdy and roomy; draws more attention.", "The largest option with 40 slots. Maximum capacity." };
private static readonly HashSet<int> _shopsIntegrated = new HashSet<int>();
private static StorableItemDefinition _safeBackpackTemplate;
private static bool _loggedSafeTemplateUnavailable;
private static bool _loggedBackpackDefinitionCreationFailure;
private static bool _loggedListingIntegrationFailureSummary;
public static void RunWhenReady()
{
MelonCoroutines.Start(WaitAndIntegrate());
}
public static bool TryAddBackpackListingsToShop(ShopInterface shop)
{
if ((Object)(object)shop == (Object)null)
{
return false;
}
if (!TryMatchHardwareStore(shop, out var _))
{
return false;
}
int instanceID = ((Object)shop).GetInstanceID();
bool flag = _shopsIntegrated.Add(instanceID);
if (AddBackpackListings(shop))
{
if (flag)
{
ModLogger.Info($"BackpackShopIntegration: Added backpack tier listings to Hardware Store (instance {instanceID}).");
}
return true;
}
ModLogger.Warn("BackpackShopIntegration: Hardware Store found but adding listings failed (see tier warnings above).");
return false;
}
[IteratorStateMachine(typeof(<WaitAndIntegrate>d__10))]
private static IEnumerator WaitAndIntegrate()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitAndIntegrate>d__10(0);
}
private static void AddToAllHardwareStoresInScene()
{
try
{
Type typeFromHandle = typeof(ShopInterface);
FieldInfo field = typeFromHandle.GetField("AllShops", BindingFlags.Static | BindingFlags.Public);
if (field != null && field.GetValue(null) is IEnumerable enumerable)
{
foreach (object item in enumerable)
{
if (item != null && TryMatchHardwareStore(item, out var shop))
{
TryAddBackpackListingsToShop(shop);
}
}
}
ShopInterface[] array = Utils.FindObjectsOfTypeSafe<ShopInterface>();
if (array == null)
{
return;
}
for (int i = 0; i < array.Length; i++)
{
if ((Object)(object)array[i] != (Object)null && TryMatchHardwareStore(array[i], out var shop2))
{
TryAddBackpackListingsToShop(shop2);
}
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: AddToAllHardwareStoresInScene", exception);
}
}
private static void LogHardwareStoreNotFound()
{
List<string> list = new List<string>();
try
{
Type typeFromHandle = typeof(ShopInterface);
FieldInfo field = typeFromHandle.GetField("AllShops", BindingFlags.Static | BindingFlags.Public);
if (field != null)
{
object value = field.GetValue(null);
if (value != null && value is IEnumerable enumerable)
{
foreach (object item in enumerable)
{
if (item != null)
{
string shopDisplayName = GetShopDisplayName(item);
if (!string.IsNullOrEmpty(shopDisplayName) && !list.Contains(shopDisplayName))
{
list.Add(shopDisplayName);
}
}
}
}
}
if (list.Count == 0)
{
ShopInterface[] array = Utils.FindObjectsOfTypeSafe<ShopInterface>();
if (array != null)
{
for (int i = 0; i < array.Length; i++)
{
string shopDisplayName2 = GetShopDisplayName(array[i]);
if (!string.IsNullOrEmpty(shopDisplayName2) && !list.Contains(shopDisplayName2))
{
list.Add(shopDisplayName2);
}
}
}
}
}
catch
{
}
if (list.Count > 0)
{
ModLogger.Warn("BackpackShopIntegration: Hardware Store not found after 30s. Shop names in game: [" + string.Join(", ", list) + "]. If your hardware store uses a different name, we can add a match for it.");
}
else
{
ModLogger.Warn("BackpackShopIntegration: Hardware Store not found after 30s (no ShopInterface instances with a name found). Shops may load later when you open them.");
}
}
private static bool TryGetHardwareStore(out ShopInterface shop)
{
shop = null;
try
{
Type typeFromHandle = typeof(ShopInterface);
FieldInfo field = typeFromHandle.GetField("AllShops", BindingFlags.Static | BindingFlags.Public);
if (field != null)
{
object value = field.GetValue(null);
if (value != null && value is IEnumerable enumerable)
{
int num = 0;
foreach (object item in enumerable)
{
if (item != null)
{
num++;
if (TryMatchHardwareStore(item, out shop))
{
return true;
}
}
}
}
}
ShopInterface[] array = Utils.FindObjectsOfTypeSafe<ShopInterface>();
if (array != null && array.Length != 0)
{
foreach (ShopInterface val in array)
{
if (!((Object)(object)val == (Object)null) && TryMatchHardwareStore(val, out shop))
{
return true;
}
}
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: Error finding Hardware Store", exception);
}
return false;
}
private static bool TryMatchHardwareStore(object shopObj, out ShopInterface shop)
{
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
shop = null;
if (shopObj == null)
{
return false;
}
string shopDisplayName = GetShopDisplayName(shopObj);
if (string.IsNullOrEmpty(shopDisplayName))
{
return false;
}
if (!string.Equals(shopDisplayName, "Hardware Store", StringComparison.OrdinalIgnoreCase) && shopDisplayName.IndexOf("Hardware", StringComparison.OrdinalIgnoreCase) < 0)
{
return false;
}
try
{
shop = (ShopInterface)shopObj;
return true;
}
catch
{
return false;
}
}
private static string GetShopDisplayName(object shopObj)
{
if (shopObj == null)
{
return null;
}
string[] array = new string[5] { "ShopName", "shopName", "Name", "name", "DisplayName" };
foreach (string memberName in array)
{
object obj = ReflectionUtils.TryGetFieldOrProperty(shopObj, memberName);
if (obj is string text && !string.IsNullOrWhiteSpace(text))
{
return text.Trim();
}
}
return null;
}
private static bool AddBackpackListings(ShopInterface shop)
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Expected O, but got Unknown
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: 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_008c: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)shop == (Object)null)
{
return false;
}
if (shop.Listings == null)
{
ModLogger.Warn("BackpackShopIntegration: Shop.Listings is null; cannot add backpack listings.");
return false;
}
Configuration instance = Configuration.Instance;
if (!LevelManagerPatch.TryGetFallbackIcon(out var texture, out var sprite))
{
texture = new Texture2D(2, 2);
texture.SetPixel(0, 0, Color.white);
texture.SetPixel(1, 0, Color.white);
texture.SetPixel(0, 1, Color.white);
texture.SetPixel(1, 1, Color.white);
texture.Apply();
sprite = Sprite.Create(texture, new Rect(0f, 0f, 2f, 2f), new Vector2(0.5f, 0.5f));
ModLogger.Warn("BackpackShopIntegration: Fallback icon resource missing; using generated placeholder icon.");
}
int num = (((Object)(object)PlayerBackpack.Instance != (Object)null) ? PlayerBackpack.Instance.EquippedTierIndex : (-1));
bool flag = false;
bool flag2 = false;
bool flag3 = false;
int num2 = 0;
int num3 = 0;
int num4 = 0;
for (int i = 0; i < Configuration.BackpackTiers.Length; i++)
{
if (!instance.TierEnabled[i])
{
RemoveTierListingFromShop(shop, "PackRat_Backpack_Tier_" + i);
continue;
}
flag2 = true;
string itemId = "PackRat_Backpack_Tier_" + i;
if (i == num)
{
RemoveTierListingFromShop(shop, itemId);
continue;
}
if (ShopHasItem(shop, itemId))
{
flag3 = true;
continue;
}
Sprite tierSprite = LevelManagerPatch.GetTierSprite(i, sprite, texture);
StorableItemDefinition val = GetRegisteredBackpackDefinition(itemId);
if ((Object)(object)val != (Object)null)
{
ConfigureBackpackTierDefinition(val, i, itemId, instance, tierSprite);
}
else
{
val = CreateBackpackTierDefinition(shop, i, itemId, instance, tierSprite);
}
if ((Object)(object)val == (Object)null)
{
num2++;
}
else if ((Object)(object)GetRegisteredBackpackDefinition(itemId) == (Object)null && !RegisterDefinition(val))
{
num3++;
ModLogger.Warn($"BackpackShopIntegration: Could not register definition for tier {i}.");
}
else if (!AddListingToShop(shop, val, sprite, texture))
{
num4++;
ModLogger.Warn($"BackpackShopIntegration: Could not add listing for tier {i}.");
}
else
{
flag = true;
}
}
if (flag)
{
_loggedListingIntegrationFailureSummary = false;
ModLogger.Info("BackpackShopIntegration: Added backpack tier listings to Hardware Store.");
}
if (!flag2 || flag3 || flag)
{
_loggedListingIntegrationFailureSummary = false;
return true;
}
if (!_loggedListingIntegrationFailureSummary)
{
_loggedListingIntegrationFailureSummary = true;
ModLogger.Warn($"BackpackShopIntegration: Eligible tiers found but none added. missingDef={num2}, registerFailed={num3}, listingFailed={num4}");
}
return false;
}
public static void RefreshBackpackListingsInAllShops()
{
AddToAllHardwareStoresInScene();
}
private static bool ShopHasItem(ShopInterface shop, string itemId)
{
try
{
if (shop.Listings == null)
{
return false;
}
Enumerator<ShopListing> enumerator = shop.Listings.GetEnumerator();
while (enumerator.MoveNext())
{
ShopListing current = enumerator.Current;
if ((Object)(object)((current != null) ? current.Item : null) != (Object)null && ((BaseItemDefinition)current.Item).ID == itemId)
{
return true;
}
}
}
catch
{
}
return false;
}
private static StorableItemDefinition CreateBackpackTierDefinition(ShopInterface shop, int tierIndex, string itemId, Configuration cfg, Sprite iconSprite)
{
try
{
StorableItemDefinition val = CreateEmptyStorableItemDefinition();
if ((Object)(object)val == (Object)null)
{
val = CloneSafeBackpackTemplate(shop);
}
if ((Object)(object)val == (Object)null && !_loggedBackpackDefinitionCreationFailure)
{
_loggedBackpackDefinitionCreationFailure = true;
ModLogger.Warn("BackpackShopIntegration: Could not create a backpack item definition. Skipping backpack listings until a valid template can be created.");
}
if ((Object)(object)val == (Object)null)
{
return null;
}
ConfigureBackpackTierDefinition(val, tierIndex, itemId, cfg, iconSprite);
return val;
}
catch (Exception exception)
{
ModLogger.Error($"BackpackShopIntegration: CreateBackpackTierDefinition tier {tierIndex}", exception);
return null;
}
}
private static void ConfigureBackpackTierDefinition(StorableItemDefinition def, int tierIndex, string itemId, Configuration cfg, Sprite iconSprite)
{
//IL_0140: 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_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)def == (Object)null)
{
return;
}
ApplyBackpackDefinitionDefaults(def);
if (!ReflectionUtils.TrySetFieldOrProperty(def, "ID", itemId))
{
ReflectionUtils.TrySetFieldOrProperty(def, "id", itemId);
}
string name = Configuration.BackpackTiers[tierIndex].Name;
if (!ReflectionUtils.TrySetFieldOrProperty(def, "Name", name))
{
ReflectionUtils.TrySetFieldOrProperty(def, "name", name);
}
if ((Object)(object)iconSprite != (Object)null)
{
string[] array = new string[7] { "Icon", "icon", "Sprite", "sprite", "ItemIcon", "itemIcon", "DisplayIcon" };
foreach (string memberName in array)
{
if (ReflectionUtils.TrySetFieldOrProperty(def, memberName, iconSprite))
{
break;
}
}
}
float num = ((tierIndex < cfg.TierPrices.Length) ? cfg.TierPrices[tierIndex] : (25f + (float)tierIndex * 50f));
ReflectionUtils.TrySetFieldOrProperty(def, "BasePurchasePrice", num);
FullRank val = ((tierIndex < cfg.TierUnlockRanks.Length) ? cfg.TierUnlockRanks[tierIndex] : Configuration.BackpackTiers[tierIndex].DefaultUnlockRank);
ReflectionUtils.TrySetFieldOrProperty(def, "RequiredRank", val);
ReflectionUtils.TrySetFieldOrProperty(def, "RequiresLevelToPurchase", true);
string value = ((tierIndex < TierDescriptions.Length) ? TierDescriptions[tierIndex] : null);
if (string.IsNullOrEmpty(value))
{
return;
}
string[] array2 = new string[8] { "Description", "description", "TooltipText", "tooltipText", "FlavorText", "flavorText", "ItemDescription", "itemDescription" };
foreach (string memberName2 in array2)
{
if (ReflectionUtils.TrySetFieldOrProperty(def, memberName2, value))
{
break;
}
}
}
private static StorableItemDefinition GetRegisteredBackpackDefinition(string itemId)
{
if (string.IsNullOrWhiteSpace(itemId))
{
return null;
}
try
{
ItemDefinition registeredItemDefinition = GetRegisteredItemDefinition(itemId);
if ((Object)(object)registeredItemDefinition == (Object)null)
{
return null;
}
return ((Il2CppObjectBase)registeredItemDefinition).TryCast<StorableItemDefinition>();
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: GetRegisteredBackpackDefinition", exception);
return null;
}
}
private static ItemDefinition GetRegisteredItemDefinition(string itemId)
{
if (string.IsNullOrWhiteSpace(itemId))
{
return null;
}
try
{
if (Registry.ItemExists(itemId))
{
return Registry.GetItem(itemId);
}
}
catch
{
}
try
{
Registry instance = Singleton<Registry>.Instance;
if ((Object)(object)instance == (Object)null)
{
return null;
}
ItemDefinition val = FindDefinitionInRegistryList(instance.ItemRegistry, itemId);
if ((Object)(object)val != (Object)null)
{
return val;
}
return FindDefinitionInRegistryList(instance.ItemsAddedAtRuntime, itemId);
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: GetRegisteredItemDefinition", exception);
return null;
}
}
private static ItemDefinition FindDefinitionInRegistryList(List<ItemRegister> registryList, string itemId)
{
if (registryList == null || string.IsNullOrWhiteSpace(itemId))
{
return null;
}
for (int i = 0; i < registryList.Count; i++)
{
ItemRegister val = registryList[i];
if (val != null && string.Equals(val.ID, itemId, StringComparison.OrdinalIgnoreCase))
{
return val.Definition;
}
}
return null;
}
private static StorableItemDefinition CloneTemplateStorableItemDefinition(ShopInterface shop)
{
if (((shop != null) ? shop.Listings : null) == null)
{
return null;
}
try
{
Enumerator<ShopListing> enumerator = shop.Listings.GetEnumerator();
while (enumerator.MoveNext())
{
ShopListing current = enumerator.Current;
if (!((Object)(object)((current != null) ? current.Item : null) == (Object)null))
{
StorableItemDefinition val = ((Il2CppObjectBase)current.Item).TryCast<StorableItemDefinition>();
if (!((Object)(object)val == (Object)null))
{
StorableItemDefinition val2 = Object.Instantiate<StorableItemDefinition>(val);
return ((Il2CppObjectBase)val2).TryCast<StorableItemDefinition>();
}
}
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: CloneTemplateStorableItemDefinition", exception);
}
return null;
}
private static StorableItemDefinition CloneSafeBackpackTemplate(ShopInterface shop)
{
if ((Object)(object)_safeBackpackTemplate == (Object)null)
{
_safeBackpackTemplate = CreateSafeBackpackTemplate(shop);
if ((Object)(object)_safeBackpackTemplate == (Object)null)
{
if (!_loggedSafeTemplateUnavailable)
{
_loggedSafeTemplateUnavailable = true;
ModLogger.Warn("BackpackShopIntegration: Safe backpack template is unavailable in IL2CPP. Backpack listings will retry once the shop can provide a valid storable-item template.");
}
return null;
}
}
try
{
StorableItemDefinition val = Object.Instantiate<StorableItemDefinition>(_safeBackpackTemplate);
return ((Il2CppObjectBase)val).TryCast<StorableItemDefinition>();
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: CloneSafeBackpackTemplate", exception);
return null;
}
}
public static StorableItemDefinition CreateSafeBackpackTemplate(ShopInterface shop = null)
{
if ((Object)(object)_safeBackpackTemplate != (Object)null)
{
return _safeBackpackTemplate;
}
try
{
_safeBackpackTemplate = CreateEmptyStorableItemDefinition();
if ((Object)(object)_safeBackpackTemplate == (Object)null && (Object)(object)shop != (Object)null)
{
_safeBackpackTemplate = CloneTemplateStorableItemDefinition(shop);
}
if ((Object)(object)_safeBackpackTemplate == (Object)null)
{
if (!_loggedSafeTemplateUnavailable)
{
_loggedSafeTemplateUnavailable = true;
ModLogger.Warn("BackpackShopIntegration: Could not create safe backpack template instance yet.");
}
return null;
}
ApplyBackpackDefinitionDefaults(_safeBackpackTemplate);
ReflectionUtils.TrySetFieldOrProperty(_safeBackpackTemplate, "ID", "PackRat_Template");
ReflectionUtils.TrySetFieldOrProperty(_safeBackpackTemplate, "Name", "Backpack");
ReflectionUtils.TrySetFieldOrProperty(_safeBackpackTemplate, "BasePurchasePrice", 0f);
ReflectionUtils.TrySetFieldOrProperty(_safeBackpackTemplate, "RequiredRank", 0);
ReflectionUtils.TrySetFieldOrProperty(_safeBackpackTemplate, "RequiresLevelToPurchase", false);
ReflectionUtils.TrySetFieldOrProperty(_safeBackpackTemplate, "Description", string.Empty);
_loggedSafeTemplateUnavailable = false;
_loggedBackpackDefinitionCreationFailure = false;
_loggedListingIntegrationFailureSummary = false;
ModLogger.Info("BackpackShopIntegration: Safe backpack template created successfully.");
return _safeBackpackTemplate;
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: CreateSafeBackpackTemplate", exception);
return null;
}
}
private static void ApplyBackpackDefinitionDefaults(StorableItemDefinition def)
{
if (!((Object)(object)def == (Object)null))
{
ReflectionUtils.TrySetFieldOrProperty(def, "Description", string.Empty);
ReflectionUtils.TrySetEnumFieldOrProperty(def, "Category", "Storage");
ReflectionUtils.TrySetFieldOrProperty(def, "StoredItem", null);
ReflectionUtils.TrySetFieldOrProperty(def, "StationItem", null);
ReflectionUtils.TrySetFieldOrProperty(def, "Equippable", null);
ReflectionUtils.TrySetFieldOrProperty(def, "CustomItemUI", null);
ReflectionUtils.TrySetFieldOrProperty(def, "CustomInfoContent", null);
ReflectionUtils.TrySetEnumFieldOrProperty(def, "legalStatus", "Legal");
ReflectionUtils.TrySetFieldOrProperty(def, "ResellMultiplier", 0.5f);
ReflectionUtils.TrySetFieldOrProperty(def, "PickpocketDifficultyMultiplier", 1f);
ReflectionUtils.TrySetFieldOrProperty(def, "CombatUtility", 0f);
}
}
private static StorableItemDefinition CreateEmptyStorableItemDefinition()
{
try
{
Type val = Il2CppType.Of<StorableItemDefinition>();
if (val != (Type)null)
{
ScriptableObject val2 = ScriptableObject.CreateInstance(val);
StorableItemDefinition val3 = ((Il2CppObjectBase)val2).TryCast<StorableItemDefinition>();
if ((Object)(object)val3 != (Object)null)
{
return val3;
}
}
ScriptableObject val4 = ScriptableObject.CreateInstance("ScheduleOne.ItemFramework.StorableItemDefinition") ?? ScriptableObject.CreateInstance("Il2CppScheduleOne.ItemFramework.StorableItemDefinition") ?? ScriptableObject.CreateInstance("StorableItemDefinition");
return (val4 != null) ? ((Il2CppObjectBase)val4).TryCast<StorableItemDefinition>() : null;
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: CreateEmptyStorableItemDefinition", exception);
return null;
}
}
private static bool RegisterDefinition(StorableItemDefinition def)
{
try
{
if ((Object)(object)def == (Object)null || string.IsNullOrWhiteSpace(((BaseItemDefinition)def).ID))
{
return false;
}
if ((Object)(object)GetRegisteredItemDefinition(((BaseItemDefinition)def).ID) != (Object)null)
{
ModLogger.Debug("BackpackShopIntegration: Definition '" + ((BaseItemDefinition)def).ID + "' is already registered; reusing existing definition.");
return true;
}
Registry instance = Singleton<Registry>.Instance;
if ((Object)(object)instance == (Object)null)
{
return false;
}
instance.AddToRegistry((ItemDefinition)(object)def);
return true;
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: RegisterDefinition", exception);
return false;
}
}
private static bool AddListingToShop(ShopInterface shop, StorableItemDefinition def, Sprite fallbackSprite, Texture2D fallbackTexture)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Expected O, but got Unknown
try
{
ShopListing val = new ShopListing
{
Item = def,
name = ((BaseItemDefinition)def).Name
};
shop.Listings.Add(val);
val.Initialize(shop);
if (!TryInvokeShopMethod(shop, "CreateListingUI", val))
{
Sprite tierSprite = LevelManagerPatch.GetTierSprite(ParseTierFromItemId(((BaseItemDefinition)def).ID), fallbackSprite, fallbackTexture);
CreateListingUI(shop, val, tierSprite);
}
TryInvokeShopMethod(shop, "RefreshUnlockStatus");
TryInvokeShopMethod(shop, "RefreshShownItems");
return true;
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: AddListingToShop", exception);
return false;
}
}
private static bool TryInvokeShopMethod(ShopInterface shop, string methodName, params object[] args)
{
try
{
if ((Object)(object)shop == (Object)null || string.IsNullOrEmpty(methodName))
{
return false;
}
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
MethodInfo[] methods = ((object)shop).GetType().GetMethods(bindingAttr);
foreach (MethodInfo methodInfo in methods)
{
if (!(methodInfo == null) && string.Equals(methodInfo.Name, methodName, StringComparison.Ordinal))
{
ParameterInfo[] parameters = methodInfo.GetParameters();
if (((args != null) ? args.Length : 0) == parameters.Length)
{
methodInfo.Invoke(shop, args);
return true;
}
}
}
}
catch (Exception ex)
{
ModLogger.Debug("BackpackShopIntegration: " + methodName + " invoke failed: " + ex.Message);
}
return false;
}
private static int ParseTierFromItemId(string itemId)
{
if (string.IsNullOrEmpty(itemId) || !itemId.StartsWith("PackRat_Backpack_Tier_", StringComparison.Ordinal))
{
return -1;
}
string s = itemId.Substring("PackRat_Backpack_Tier_".Length);
int result;
return int.TryParse(s, out result) ? result : (-1);
}
private static void CreateListingUI(ShopInterface shop, ShopListing listing, Sprite iconSprite)
{
try
{
object obj = ReflectionUtils.TryGetFieldOrProperty(shop, "ListingUIPrefab");
object obj2 = ReflectionUtils.TryGetFieldOrProperty(shop, "ListingContainer");
if (obj == null || obj2 == null)
{
ModLogger.Warn("BackpackShopIntegration: Shop missing ListingUIPrefab or ListingContainer.");
return;
}
object obj3 = ((obj is Component) ? obj : null);
GameObject val = ((obj3 != null) ? ((Component)obj3).gameObject : null);
Transform val2 = (Transform)((obj2 is Transform) ? obj2 : null);
if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
{
return;
}
GameObject val3 = Object.Instantiate<GameObject>(val, val2);
ListingUI component = val3.GetComponent<ListingUI>();
if ((Object)(object)component == (Object)null)
{
Object.Destroy((Object)(object)val3);
return;
}
component.Initialize(listing);
if ((Object)(object)iconSprite != (Object)null && (Object)(object)component.Icon != (Object)null)
{
component.Icon.sprite = iconSprite;
}
BindListingUIEvents(shop, component);
AddToListingUICollection(shop, component);
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: CreateListingUI", exception);
}
}
private static void BindListingUIEvents(ShopInterface shop, ListingUI listingUI)
{
try
{
listingUI.onClicked = Action.op_Implicit((Action)delegate
{
shop.ListingClicked(listingUI);
});
listingUI.onDropdownClicked = Action.op_Implicit((Action)delegate
{
shop.DropdownClicked(listingUI);
});
listingUI.hoverStart = Action.op_Implicit((Action)delegate
{
shop.EntryHovered(listingUI);
});
listingUI.hoverEnd = Action.op_Implicit((Action)delegate
{
shop.EntryUnhovered();
});
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: BindListingUIEvents", exception);
}
}
private static void AddToListingUICollection(ShopInterface shop, ListingUI listingUI)
{
try
{
FieldInfo field = typeof(ShopInterface).GetField("listingUI", BindingFlags.Instance | BindingFlags.NonPublic);
if (!(field == null))
{
object value = field.GetValue(shop);
if (value != null && value is List<ListingUI> val)
{
val.Add(listingUI);
}
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: AddToListingUICollection", exception);
}
}
public static bool IsBackpackTierPurchase(string itemId, out int tierIndex)
{
tierIndex = ParseTierFromItemId(itemId ?? "");
return tierIndex >= 0;
}
public static void RemoveTierListingFromAllShops(int tierIndex)
{
if (tierIndex < 0 || tierIndex >= Configuration.BackpackTiers.Length)
{
return;
}
string itemId = "PackRat_Backpack_Tier_" + tierIndex;
List<int> list = new List<int>(_shopsIntegrated);
foreach (int item in list)
{
ShopInterface val = FindShopByInstanceId(item);
if ((Object)(object)val != (Object)null)
{
RemoveTierListingFromShop(val, itemId);
}
}
}
private static ShopInterface FindShopByInstanceId(int instanceId)
{
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Expected O, but got Unknown
try
{
Type typeFromHandle = typeof(ShopInterface);
FieldInfo field = typeFromHandle.GetField("AllShops", BindingFlags.Static | BindingFlags.Public);
if (field != null && field.GetValue(null) is IEnumerable enumerable)
{
foreach (object item in enumerable)
{
if (item != null)
{
object obj = ((item is Object) ? item : null);
if (obj != null && ((Object)obj).GetInstanceID() == instanceId)
{
return (ShopInterface)item;
}
}
}
}
ShopInterface[] array = Utils.FindObjectsOfTypeSafe<ShopInterface>();
if (array != null)
{
for (int i = 0; i < array.Length; i++)
{
if ((Object)(object)array[i] != (Object)null && ((Object)array[i]).GetInstanceID() == instanceId)
{
return array[i];
}
}
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: FindShopByInstanceId", exception);
}
return null;
}
private static void RemoveTierListingFromShop(ShopInterface shop, string itemId)
{
if (((shop != null) ? shop.Listings : null) == null)
{
return;
}
try
{
object obj = null;
Enumerator<ShopListing> enumerator = shop.Listings.GetEnumerator();
while (enumerator.MoveNext())
{
ShopListing current = enumerator.Current;
if ((Object)(object)((current != null) ? current.Item : null) != (Object)null && ((BaseItemDefinition)current.Item).ID == itemId)
{
obj = current;
break;
}
}
if (obj != null)
{
RemoveListingFromList(shop.Listings, obj);
RemoveAndDestroyListingUI(shop, obj);
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: RemoveTierListingFromShop", exception);
}
}
private static int GetListCount(object list)
{
if (list == null)
{
return 0;
}
object obj = ReflectionUtils.TryGetFieldOrProperty(list, "Count") ?? ReflectionUtils.TryGetFieldOrProperty(list, "count");
if (obj is int result)
{
return result;
}
if (obj is long num)
{
return (int)num;
}
return 0;
}
private static void RemoveListingFromList(object list, object listing)
{
if (list == null || listing == null)
{
return;
}
try
{
IList val = (IList)((list is IList) ? list : null);
if (val == null)
{
return;
}
int listCount = GetListCount(val);
for (int i = 0; i < listCount; i++)
{
Object val2 = val[i];
if (val2 != null && (((object)val2).Equals(listing) || val2 == listing))
{
val.RemoveAt(i);
break;
}
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: RemoveListingFromList", exception);
}
}
private static void RemoveAndDestroyListingUI(ShopInterface shop, object listing)
{
if ((Object)(object)shop == (Object)null || listing == null)
{
return;
}
try
{
object obj = typeof(ShopInterface).GetField("listingUI", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(shop);
if (obj == null)
{
return;
}
object obj2 = ReflectionUtils.TryGetFieldOrProperty(obj, "Count") ?? ReflectionUtils.TryGetFieldOrProperty(obj, "count");
int num2 = ((obj2 is int num) ? num : 0);
if (obj2 is long num3)
{
num2 = (int)num3;
}
for (int num4 = num2 - 1; num4 >= 0; num4--)
{
object obj3 = (obj.GetType().GetMethod("get_Item", new Type[1] { typeof(int) }) ?? obj.GetType().GetMethod("Get", new Type[1] { typeof(int) }))?.Invoke(obj, new object[1] { num4 });
if (obj3 != null)
{
object obj4 = ReflectionUtils.TryGetFieldOrProperty(obj3, "Listing") ?? ReflectionUtils.TryGetFieldOrProperty(obj3, "listing");
if (obj4 == listing)
{
object obj5 = ((obj3 is Component) ? obj3 : null);
GameObject val = ((obj5 != null) ? ((Component)obj5).gameObject : null);
if ((Object)(object)val != (Object)null)
{
Object.Destroy((Object)(object)val);
}
IList val2 = (IList)((obj is IList) ? obj : null);
if (val2 != null)
{
val2.RemoveAt(num4);
}
break;
}
}
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: RemoveAndDestroyListingUI", exception);
}
}
}
}
namespace PackRat.Patches
{
[HarmonyPatch(typeof(ShopInterface))]
public static class BackpackPurchasePatch
{
[HarmonyPatch("ListingClicked", new Type[] { typeof(ListingUI) })]
[HarmonyPrefix]
public static bool ListingClicked_Prefix(ShopInterface __instance, ListingUI listingUI)
{
try
{
if ((Object)(object)listingUI == (Object)null)
{
return true;
}
object obj = ReflectionUtils.TryGetFieldOrProperty(listingUI, "Listing") ?? ReflectionUtils.TryGetFieldOrProperty(listingUI, "listing");
if (obj == null)
{
return true;
}
object obj2 = ReflectionUtils.TryGetFieldOrProperty(obj, "Item");
StorableItemDefinition val = null;
Object val2 = (Object)((obj2 is Object) ? obj2 : null);
val = (StorableItemDefinition)((val2 == null) ? ((obj2 is StorableItemDefinition) ? obj2 : null) : ((Il2CppObjectBase)val2).TryCast<StorableItemDefinition>());
if (val == null || ((BaseItemDefinition)val).ID == null || !((BaseItemDefinition)val).ID.StartsWith("PackRat_Backpack_Tier_", StringComparison.Ordinal))
{
return true;
}
if (BackpackShopIntegration.IsBackpackTierPurchase(((BaseItemDefinition)val).ID, out var tierIndex) && (Object)(object)PlayerBackpack.Instance != (Object)null && tierIndex == PlayerBackpack.Instance.EquippedTierIndex)
{
ModLogger.Info($"Blocked purchase selection for currently equipped backpack tier {tierIndex}.");
return false;
}
return true;
}
catch (Exception exception)
{
ModLogger.Error("BackpackPurchasePatch: ListingClicked prefix error", exception);
return true;
}
}
}
[HarmonyPatch(typeof(BodySearchBehaviour))]
public static class BodySearchBehaviourPatch
{
[CompilerGenerated]
private sealed class <CheckForItems>d__1 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public BodySearchBehaviour behaviour;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <CheckForItems>d__1(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Expected O, but got Unknown
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
((NPC)behaviour.officer).DialogueHandler.ShowWorldspaceDialogue("Hold on, let me see your backpack as well.", 5f);
<>2__current = (object)new WaitForSeconds(3f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
Singleton<BodySearchScreen>.Instance.IsOpen = false;
behaviour.ConcludeSearch(!PlayerBackpack.Instance.ContainsItemsOfInterest(behaviour.MaxStealthLevel));
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[HarmonyPatch("SearchClean")]
[HarmonyPrefix]
public static bool SearchClean(BodySearchBehaviour __instance)
{
if ((Object)(object)PlayerBackpack.Instance == (Object)null || !Configuration.Instance.EnableSearch || !PlayerBackpack.Instance.IsUnlocked || !PlayerBackpack.Instance.IsPoliceSearchable)
{
return true;
}
Singleton<BodySearchScreen>.Instance.onSearchClear.RemoveListener(UnityAction.op_Implicit((Action)__instance.SearchClean));
Singleton<BodySearchScreen>.Instance.onSearchFail.RemoveListener(UnityAction.op_Implicit((Action)__instance.SearchFail));
Singleton<BodySearchScreen>.Instance.IsOpen = true;
MelonCoroutines.Start(CheckForItems(__instance));
return false;
}
[IteratorStateMachine(typeof(<CheckForItems>d__1))]
private static IEnumerator CheckForItems(BodySearchBehaviour behaviour)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <CheckForItems>d__1(0)
{
behaviour = behaviour
};
}
}
[HarmonyPatch(typeof(Cart))]
public static class CartPatch
{
[HarmonyPatch("GetWarning")]
[HarmonyPostfix]
public static void GetWarning(Cart __instance, ref bool __result, ref string warning)
{
PlayerBackpack instance = PlayerBackpack.Instance;
if (!((Object)(object)instance == (Object)null) && instance.IsUnlocked && !warning.StartsWith("Vehicle") && __result)
{
List<ItemSlot> itemSlots = instance.ItemSlots;
itemSlots.InsertRange(0, ((Il2CppObjectBase)PlayerSingleton<PlayerInventory>.Instance.hotbarSlots).Cast<IEnumerable<ItemSlot>>());
if (__instance.Shop.WillCartFit(itemSlots))
{
warning = "Inventory won't fit everything. Some items will be placed in your backpack.";
}
}
}
}
[HarmonyPatch(typeof(HandoverScreen))]
public static class HandoverScreenPatch
{
private sealed class PanelState
{
public RectTransform BackpackContainer;
public RectTransform BackpackSlotContainer;
public RectTransform BackpackHeaderRoot;
public RectTransform PagingRoot;
public RectTransform VehicleContainer;
public Component SourceTitleLabel;
public Component SourceSubtitleLabel;
public Component ClonedTitleLabel;
public Component ClonedSubtitleLabel;
public Component OverlayTitleLabel;
public Component OverlaySubtitleLabel;
public ItemSlotUI[] SlotUIs;
public Button PrevButton;
public Button NextButton;
public Button ToggleButton;
public Text PageLabel;
public Action PrevAction;
public Action NextAction;
public Action ToggleAction;
public Vector2 VehicleOriginalAnchoredPos;
public int CurrentPage;
public int SlotsPerPage;
public bool ShowingVehicle;
public int LastPageInputFrame;
public bool Initialized;
}
private sealed class HeaderCandidate
{
public Component Label;
public float LocalY;
public float FontSize;
}
[CompilerGenerated]
private sealed class <ReapplyHeaderNextFrame>d__9 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public HandoverScreen screen;
public PanelState panel;
private int <i>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <ReapplyHeaderNextFrame>d__9(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
if ((Object)(object)screen == (Object)null || panel == null)
{
return false;
}
<i>5__1 = 0;
break;
case 1:
<>1__state = -1;
if ((Object)(object)screen == (Object)null || panel == null || (Object)(object)panel.BackpackContainer == (Object)null || !((Component)panel.BackpackContainer).gameObject.activeSelf)
{
return false;
}
if (panel.ShowingVehicle)
{
return false;
}
if ((Object)(object)panel.VehicleContainer != (Object)null && ((Component)panel.VehicleContainer).gameObject.activeSelf)
{
((Component)panel.VehicleContainer).gameObject.SetActive(false);
}
ApplyPrimaryHeaderForMode(screen, panel, showingVehicle: false);
<i>5__1++;
break;
}
if (<i>5__1 < 3)
{
<>2__current = null;
<>1__state = 1;
return true;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private const float VehicleMaxDistance = 20f;
private const string VehicleHeaderTitle = "Vehicle";
private const string VehicleHeaderSubtitle = "This is the vehicle you last drove.\nMust be within 20 meters.";
private static readonly Dictionary<int, PanelState> States = new Dictionary<int, PanelState>();
private const int HeaderReapplyFrameCount = 3;
[HarmonyPatch("Start")]
[HarmonyPostfix]
public static void Start(HandoverScreen __instance)
{
try
{
PruneDeadStates();
EnsurePanel(__instance);
}
catch (Exception exception)
{
ModLogger.Error("HandoverScreenPatch.Start", exception);
}
}
[HarmonyPatch("Open")]
[HarmonyPostfix]
public static void Open(HandoverScreen __instance)
{
try
{
PruneDeadStates();
if (!HasBackpack())
{
HidePanelAndRestoreVehicle(__instance);
return;
}
PanelState panelState = EnsurePanel(__instance);
if (panelState != null && !((Object)(object)panelState.BackpackContainer == (Object)null))
{
panelState.CurrentPage = 0;
panelState.SlotsPerPage = ((panelState.SlotUIs != null) ? panelState.SlotUIs.Length : 0);
panelState.ShowingVehicle = false;
((Component)panelState.BackpackContainer).gameObject.SetActive(true);
if ((Object)(object)panelState.PagingRoot != (Object)null)
{
((Component)panelState.PagingRoot).gameObject.SetActive(true);
}
UpdateBackpackHeaderTexts(panelState);
bool flag = HasNearbyVehicleStorage();
if ((Object)(object)__instance.NoVehicle != (Object)null)
{
__instance.NoVehicle.SetActive(!flag && !((Component)panelState.BackpackContainer).gameObject.activeSelf);
}
ApplyVisibleStorageMode(panelState, flag);
if ((Object)(object)__instance.NoVehicle != (Object)null)
{
__instance.NoVehicle.SetActive(false);
}
if ((Object)(object)panelState.BackpackContainer != (Object)null)
{
((Component)panelState.BackpackContainer).gameObject.SetActive(true);
}
if ((Object)(object)panelState.BackpackSlotContainer != (Object)null)
{
((Component)panelState.BackpackSlotContainer).gameObject.SetActive(true);
}
if ((Object)(object)panelState.VehicleContainer != (Object)null)
{
((Component)panelState.VehicleContainer).gameObject.SetActive(false);
}
ApplyPrimaryHeaderForMode(__instance, panelState, panelState.ShowingVehicle);
MelonCoroutines.Start(ReapplyHeaderNextFrame(__instance, panelState));
ApplyBackpackPage(panelState);
RebuildQuickMove(__instance, flag);
}
}
catch (Exception exception)
{
ModLogger.Error("HandoverScreenPatch.Open", exception);
}
}
[IteratorStateMachine(typeof(<ReapplyHeaderNextFrame>d__9))]
private static IEnumerator ReapplyHeaderNextFrame(HandoverScreen screen, PanelState panel)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <ReapplyHeaderNextFrame>d__9(0)
{
screen = screen,
panel = panel
};
}
[HarmonyPatch("Update")]
[HarmonyPostfix]
public static void Update(HandoverScreen __instance)
{
PruneDeadStates();
if ((Object)(object)__instance == (Object)null || !States.TryGetValue(((Object)__instance).GetInstanceID(), out var value) || (Object)(object)value.BackpackContainer == (Object)null || !((Component)value.BackpackContainer).gameObject.activeSelf || value.ShowingVehicle)
{
return;
}
if ((Object)(object)value.VehicleContainer != (Object)null && ((Component)value.VehicleContainer).gameObject.activeSelf)
{
((Component)value.VehicleContainer).gameObject.SetActive(false);
}
ApplyPrimaryHeaderForMode(__instance, value, showingVehicle: false);
if ((Object)(object)value.BackpackHeaderRoot != (Object)null && ((Component)value.BackpackHeaderRoot).gameObject.activeSelf)
{
((Transform)value.BackpackHeaderRoot).SetAsLastSibling();
Canvas component = ((Component)value.BackpackHeaderRoot).GetComponent<Canvas>();
if ((Object)(object)component != (Object)null && component.overrideSorting && component.sortingOrder != 9999)
{
component.sortingOrder = 9999;
}
}
}
[HarmonyPatch("Close")]
[HarmonyPostfix]
public static void Close(HandoverScreen __instance)
{
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
try
{
if (States.TryGetValue(((Object)__instance).GetInstanceID(), out var value))
{
ClearSlotAssignments(value);
if ((Object)(object)value.BackpackContainer != (Object)null)
{
((Component)value.BackpackContainer).gameObject.SetActive(false);
}
if ((Object)(object)value.PagingRoot != (Object)null)
{
((Component)value.PagingRoot).gameObject.SetActive(false);
}
HideOverlayHeader(value);
SetHeaderPairActive(value.SourceTitleLabel, value.SourceSubtitleLabel, active: true);
if ((Object)(object)value.VehicleContainer != (Object)null)
{
value.VehicleContainer.anchoredPosition = value.VehicleOriginalAnchoredPos;
}
}
}
catch (Exception exception)
{
ModLogger.Error("HandoverScreenPatch.Close", exception);
}
}
private static PanelState EnsurePanel(HandoverScreen screen)
{
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Unknown result type (might be due to invalid IL or missing references)
PruneDeadStates();
if ((Object)(object)screen == (Object)null)
{
return null;
}
int instanceID = ((Object)screen).GetInstanceID();
if (States.TryGetValue(instanceID, out var value) && value.Initialized && IsComponentAlive((Component)(object)value.BackpackContainer) && IsComponentAlive((Component)(object)value.VehicleContainer) && ((Object)(object)value.BackpackHeaderRoot == (Object)null || IsComponentAlive((Component)(object)value.BackpackHeaderRoot)) && IsComponentAlive((Component)(object)value.PagingRoot) && IsComponentAlive((Component)(object)value.PrevButton) && IsComponentAlive((Component)(object)value.NextButton) && IsComponentAlive((Component)(object)value.ToggleButton) && IsComponentAlive((Component)(object)value.PageLabel))
{
RefreshHeaderBindings(value, screen);
return value;
}
PanelState panelState = value ?? new PanelState();
panelState.VehicleContainer = screen.VehicleContainer;
if ((Object)(object)panelState.VehicleContainer == (Object)null)
{
return null;
}
panelState.VehicleOriginalAnchoredPos = panelState.VehicleContainer.anchoredPosition;
if (!IsComponentAlive((Component)(object)panelState.BackpackContainer))
{
panelState.BackpackContainer = null;
}
if ((Object)(object)panelState.BackpackContainer == (Object)null)
{
RectTransform val = Object.Instantiate<RectTransform>(panelState.VehicleContainer, ((Transform)panelState.VehicleContainer).parent);
((Object)val).name = "BackpackContainer";
val.anchoredPosition = panelState.VehicleOriginalAnchoredPos;
((Transform)val).localScale = ((Transform)panelState.VehicleContainer).localScale;
((Component)val).gameObject.SetActive(false);
panelState.BackpackContainer = val;
}
panelState.BackpackSlotContainer = FindMatchingRectTransform(panelState.BackpackContainer, screen.VehicleSlotContainer);
RectTransform val2 = (((Object)(object)panelState.BackpackSlotContainer != (Object)null) ? panelState.BackpackSlotContainer : panelState.BackpackContainer);
panelState.SlotUIs = Il2CppArrayBase<ItemSlotUI>.op_Implicit(((Component)val2).GetComponentsInChildren<ItemSlotUI>(false));
if (panelState.SlotUIs == null || panelState.SlotUIs.Length == 0)
{
panelState.SlotUIs = Il2CppArrayBase<ItemSlotUI>.op_Implicit(((Component)val2).GetComponentsInChildren<ItemSlotUI>(true));
}
RefreshHeaderBindings(panelState, screen);
EnsurePagingControls(panelState);
panelState.Initialized = true;
States[instanceID] = panelState;
return panelState;
}
private static void PruneDeadStates()
{
if (States.Count == 0)
{
return;
}
List<int> list = new List<int>();
foreach (KeyValuePair<int, PanelState> state in States)
{
PanelState value = state.Value;
if (value == null)
{
list.Add(state.Key);
}
else if (!IsComponentAlive((Component)(object)value.VehicleContainer) && !IsComponentAlive((Component)(object)value.BackpackContainer) && !IsComponentAlive((Component)(object)value.PagingRoot) && !IsComponentAlive((Component)(object)value.BackpackHeaderRoot))
{
list.Add(state.Key);
}
}
for (int i = 0; i < list.Count; i++)
{
States.Remove(list[i]);
}
}
private static void RefreshHeaderBindings(PanelState state, HandoverScreen screen)
{
if (state != null)
{
ResolveLabels(state, screen);
EnsureBackpackHeader(state);
}
}
private static void ResolveLabels(PanelState state, HandoverScreen screen)
{
ResolveHeaderPairInContainer(state.VehicleContainer, (Transform)(object)((screen != null) ? screen.VehicleSlotContainer : null), null, null, out state.SourceTitleLabel, out state.SourceSubtitleLabel);
ResolveHeaderPairInContainer(state.BackpackContainer, (Transform)(object)state.BackpackSlotContainer, (Transform)(object)state.PagingRoot, (Transform)(object)state.BackpackHeaderRoot, out state.ClonedTitleLabel, out state.ClonedSubtitleLabel);
}
private static void ResolveHeaderPairInContainer(RectTransform container, Transform slotContainer, Transform pagingRoot, Transform overlayRoot, out Component titleLabel, out Component subtitleLabel)
{
titleLabel = null;
subtitleLabel = null;
if ((Object)(object)container == (Object)null)
{
return;
}
Il2CppArrayBase<Component> componentsInChildren = ((Component)container).GetComponentsInChildren<Component>(true);
List<Component> list = new List<Component>();
for (int i = 0; i < componentsInChildren.Length; i++)
{
Component val = componentsInChildren[i];
if (!((Object)(object)val == (Object)null) && IsTextLikeComponent(val) && !IsUnderTransform(val, slotContainer) && !IsUnderTransform(val, pagingRoot) && !IsUnderTransform(val, overlayRoot))
{
list.Add(val);
}
}
if (list.Count == 0)
{
return;
}
titleLabel = FindNamedHeaderLabel(container, slotContainer, pagingRoot, overlayRoot, "Title");
subtitleLabel = FindNamedHeaderLabel(container, slotContainer, pagingRoot, overlayRoot, "Subtitle");
foreach (Component item in list)
{
string text = NormalizeLabelText(GetLabelText(item));
if ((Object)(object)titleLabel == (Object)null && text.Equals("Vehicle", StringComparison.OrdinalIgnoreCase))
{
titleLabel = item;
}
else if ((Object)(object)subtitleLabel == (Object)null && (text.Contains("vehicle you last drove", StringComparison.OrdinalIgnoreCase) || text.Contains("within 20 meters", StringComparison.OrdinalIgnoreCase)))
{
subtitleLabel = item;
}
}
if ((Object)(object)titleLabel != (Object)null && (Object)(object)subtitleLabel != (Object)null)
{
return;
}
List<HeaderCandidate> list2 = new List<HeaderCandidate>(list.Count);
for (int j = 0; j < list.Count; j++)
{
Component val2 = list[j];
list2.Add(new HeaderCandidate
{
Label = val2,
LocalY = GetLocalY(container, val2),
FontSize = GetFontSize(val2)
});
}
list2.Sort(CompareHeaderCandidates);
if ((Object)(object)titleLabel == (Object)null && list2.Count > 0)
{
titleLabel = list2[0].Label;
}
if (!((Object)(object)subtitleLabel == (Object)null))
{
return;
}
for (int k = 0; k < list2.Count; k++)
{
Component label = list2[k].Label;
if (!((Object)(object)label == (Object)null) && !((Object)(object)label == (Object)(object)titleLabel))
{
subtitleLabel = label;
break;
}
}
}
private static Component FindNamedHeaderLabel(RectTransform container, Transform slotContainer, Transform pagingRoot, Transform overlayRoot, string targetName)
{
if ((Object)(object)container == (Object)null || string.IsNullOrEmpty(targetName))
{
return null;
}
Il2CppArrayBase<Transform> componentsInChildren = ((Component)container).GetComponentsInChildren<Transform>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
Transform val = componentsInChildren[i];
if (!((Object)(object)val == (Object)null) && string.Equals(((Object)val).name, targetName, StringComparison.OrdinalIgnoreCase) && (!((Object)(object)slotContainer != (Object)null) || (!((Object)(object)val == (Object)(object)slotContainer) && !val.IsChildOf(slotContainer))) && (!((Object)(object)pagingRoot != (Object)null) || (!((Object)(object)val == (Object)(object)pagingRoot) && !val.IsChildOf(pagingRoot))) && (!((Object)(object)overlayRoot != (Object)null) || (!((Object)(object)val == (Object)(object)overlayRoot) && !val.IsChildOf(overlayRoot))))
{
Component textLikeComponent = GetTextLikeComponent(((Component)val).gameObject);
if ((Object)(object)textLikeComponent != (Object)null)
{
return textLikeComponent;
}
Component val2 = FindFirstTextLikeInSubtree(val);
if ((Object)(object)val2 != (Object)null)
{
return val2;
}
}
}
return null;
}
private static Component FindFirstTextLikeInSubtree(Transform root)
{
if ((Object)(object)root == (Object)null)
{
return null;
}
Il2CppArrayBase<Component> componentsInChildren = ((Component)root).GetComponentsInChildren<Component>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
Component val = componentsInChildren[i];
if ((Object)(object)val != (Object)null && IsTextLikeComponent(val))
{
return val;
}
}
return null;
}
private static int CompareHeaderCandidates(HeaderCandidate left, HeaderCandidate right)
{
if (left == right)
{
return 0;
}
if (left == null)
{
return 1;
}
if (right == null)
{
return -1;
}
int num = right.LocalY.CompareTo(left.LocalY);
if (num != 0)
{
return num;
}
return right.FontSize.CompareTo(left.FontSize);
}
private static float GetLocalY(RectTransform container, Component component)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: 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)container == (Object)null || (Object)(object)component == (Object)null || (Object)(object)component.transform == (Object)null)
{
return float.MinValue;
}
try
{
Vector3 val = ((Transform)container).InverseTransformPoint(component.transform.position);
return val.y;
}
catch
{
return float.MinValue;
}
}
private static float GetFontSize(Component label)
{
if ((Object)(object)label == (Object)null)
{
return 0f;
}
TextMeshProUGUI val = (TextMeshProUGUI)(object)((label is TextMeshProUGUI) ? label : null);
if (val != null)
{
try
{
return ((TMP_Text)val).fontSize;
}
catch
{
}
}
Text val2 = (Text)(object)((label is Text) ? label : null);
if (val2 != null)
{
return val2.fontSize;
}
object obj2 = ReflectionUtils.TryGetFieldOrProperty(label, "fontSize");
if (obj2 is float result)
{
return result;
}
if (obj2 is int num)
{
return num;
}
return 0f;
}
private static Component GetTextLikeComponent(GameObject gameObject)
{
if ((Object)(object)gameObject == (Object)null)
{
return null;
}
TextMeshProUGUI tmpLabel = GetTmpLabel(gameObject);
if ((Object)(object)tmpLabel != (Object)null)
{
return (Component)(object)tmpLabel;
}
Text componentSafe = Utils.GetComponentSafe<Text>(gameObject);
if ((Object)(object)componentSafe != (Object)null)
{
return (Component)(object)componentSafe;
}
Il2CppArrayBase<Component> components = gameObject.GetComponents<Component>();
for (int i = 0; i < components.Length; i++)
{
Component val = components[i];
if ((Object)(object)val != (Object)null && IsTextLikeComponent(val))
{
return val;
}
}
return null;
}
private static void EnsureBackpackHeader(PanelState state)
{
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Expected O, but got Unknown
if ((Object)(object)state?.BackpackContainer == (Object)null || (Object)(object)state.SourceTitleLabel == (Object)null || (Object)(object)state.SourceSubtitleLabel == (Object)null)
{
return;
}
RectTransform backpackContainer = state.BackpackContainer;
RectTransform val = null;
if ((Object)(object)state.BackpackHeaderRoot != (Object)null && IsComponentAlive((Component)(object)state.BackpackHeaderRoot))
{
val = state.BackpackHeaderRoot;
}
if ((Object)(object)val != (Object)null && (Object)(object)((Transform)val).parent != (Object)(object)backpackContainer)
{
((Transform)val).SetParent((Transform)(object)backpackContainer, false);
}
if ((Object)(object)val == (Object)null)
{
Transform val2 = ((Transform)backpackContainer).Find("PackRat_BackpackHeader");
val = (RectTransform)(object)((val2 is RectTransform) ? val2 : null);
}
if ((Object)(object)val == (Object)null)
{
GameObject val3 = new GameObject("PackRat_BackpackHeader");
val = val3.AddComponent<RectTransform>();
((Transform)val).SetParent((Transform)(object)backpackContainer, false);
}
state.BackpackHeaderRoot = val;
EnsureIgnoredByLayout(val);
ResetHeaderOverlayRoot(val);
state.OverlayTitleLabel = EnsureOverlayLabel(val, "PackRat_BackpackTitle", state.SourceTitleLabel);
state.OverlaySubtitleLabel = EnsureOverlayLabel(val, "PackRat_BackpackSubtitle", state.SourceSubtitleLabel);
UpdateBackpackHeaderLayout(state);
if (TryGetGameObject((Component)(object)val, out var gameObject) && TryGetGameObject((Component)(object)backpackContainer, out var gameObject2))
{
SetLayerRecursively(gameObject, gameObject2.layer);
((Transform)val).SetAsLastSibling();
Canvas componentInParent = ((Component)backpackContainer).GetComponentInParent<Canvas>();
Canvas val4 = gameObject.GetComponent<Canvas>();
if ((Object)(object)val4 == (Object)null)
{
val4 = gameObject.AddComponent<Canvas>();
}
val4.overrideSorting = true;
if ((Object)(object)componentInParent != (Object)null)
{
val4.sortingLayerID = componentInParent.sortingLayerID;
val4.sortingOrder = componentInParent.sortingOrder + 210;
}
else
{
val4.sortingOrder = 5010;
}
}
UpdateBackpackHeaderTexts(state);
}
private static void UpdateBackpackHeaderLayout(PanelState state)
{
//IL_0043: 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_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)state?.BackpackHeaderRoot == (Object)null) && !((Object)(object)state.BackpackContainer == (Object)null))
{
RectTransform backpackHeaderRoot = state.BackpackHeaderRoot;
EnsureIgnoredByLayout(backpackHeaderRoot);
backpackHeaderRoot.anchorMin = new Vector2(0.5f, 1f);
backpackHeaderRoot.anchorMax = new Vector2(0.5f, 1f);
backpackHeaderRoot.pivot = new Vector2(0.5f, 1f);
backpackHeaderRoot.anchoredPosition = new Vector2(0f, -8f);
((Transform)backpackHeaderRoot).localScale = Vector3.one;
}
}
private static void ResetHeaderOverlayRoot(RectTransform headerRoot)
{
//IL_001c: 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_0048: 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_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: 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)
if (!((Object)(object)headerRoot == (Object)null))
{
headerRoot.anchorMin = new Vector2(0.5f, 0.5f);
headerRoot.anchorMax = new Vector2(0.5f, 0.5f);
headerRoot.pivot = new Vector2(0.5f, 0.5f);
headerRoot.anchoredPosition3D = Vector3.zero;
((Transform)headerRoot).localRotation = Quaternion.identity;
((Transform)headerRoot).localScale = Vector3.one;
headerRoot.sizeDelta = Vector2.zero;
headerRoot.offsetMin = Vector2.zero;
headerRoot.offsetMax = Vector2.zero;
}
}
private static Component EnsureOverlayLabel(RectTransform parent, string name, Component sourceLabel)
{
if ((Object)(object)parent == (Object)null || (Object)(object)sourceLabel == (Object)null)
{
return null;
}
Transform val = ((Transform)parent).Find(name);
Component val2 = null;
if ((Object)(object)val != (Object)null)
{
val2 = GetTextLikeComponent(((Component)val).gameObject);
}
if ((Object)(object)val2 == (Object)null)
{
GameObject gameObject = sourceLabel.gameObject;
if ((Object)(object)gameObject == (Object)null)
{
return null;
}
GameObject val3 = Object.Instantiate<GameObject>(gameObject, (Transform)(object)parent);
((Object)val3).name = name;
val2 = GetTextLikeComponent(val3);
}
if ((Object)(object)val2 == (Object)null)
{
return null;
}
if (TryGetRectTransform(sourceLabel, out var rectTransform) && TryGetRectTransform(val2, out var rectTransform2))
{
CopyRectTransform(rectTransform, rectTransform2);
}
CopyLabelPresentation(sourceLabel, val2);
return val2;
}
private static void CopyRectTransform(RectTransform source, RectTransform target)
{
//IL_001c: 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_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: 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_006a: 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_0084: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null))
{
target.anchorMin = source.anchorMin;
target.anchorMax = source.anchorMax;
target.pivot = source.pivot;
target.anchoredPosition3D = source.anchoredPosition3D;
target.sizeDelta = source.sizeDelta;
target.offsetMin = source.offsetMin;
target.offsetMax = source.offsetMax;
((Transform)target).localRotation = ((Transform)source).localRotation;
((Transform)target).localScale = ((Transform)source).localScale;
}
}
private static void CopyLabelPresentation(Component source, Component target)
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)source == (Object)null || (Object)(object)target == (Object)null)
{
return;
}
TextMeshProUGUI val = (TextMeshProUGUI)(object)((source is TextMeshProUGUI) ? source : null);
if (val != null)
{
TextMeshProUGUI val2 = (TextMeshProUGUI)(object)((target is TextMeshProUGUI) ? target : null);
if (val2 != null)
{
((TMP_Text)val2).font = ((TMP_Text)val).font;
((TMP_Text)val2).fontSize = ((TMP_Text)val).fontSize;
((TMP_Text)val2).fontStyle = ((TMP_Text)val).fontStyle;
((TMP_Text)val2).alignment = ((TMP_Text)val).alignment;
((Graphic)val2).color = ((Graphic)val).color;
((Graphic)val2).raycastTarget = false;
return;
}
}
Text val3 = (Text)(object)((source is Text) ? source : null);
if (val3 != null)
{
Text val4 = (Text)(object)((target is Text) ? target : null);
if (val4 != null)
{
val4.font = val3.font;
val4.fontSize = val3.fontSize;
val4.fontStyle = val3.fontStyle;
val4.alignment = val3.alignment;
((Graphic)val4).color = ((Graphic)val3).color;
((Graphic)val4).raycastTarget = false;
}
}
}
private static void EnsureIgnoredByLayout(RectTransform rectTransform)
{
if (!((Object)(object)rectTransform == (Object)null))
{
LayoutElement orAddComponentSafe = Utils.GetOrAddComponentSafe<LayoutElement>(((Component)rectTransform).gameObject);
if ((Object)(object)orAddComponentSafe != (Object)null)
{
orAddComponentSafe.ignoreLayout = true;
}
}
}
private static string GetBackpackDisplayName()
{
PlayerBackpack instance = PlayerBackpack.Instance;
string text = instance?.CurrentTier?.Name;
if (!string.IsNullOrEmpty(text))
{
return text;
}
int num = instance?.CurrentTierIndex ?? (-1);
if (num >= 0 && num < Configuration.BackpackTiers.Length)
{
return Configuration.BackpackTiers[num].Name;
}
return "Backpack";
}
private static void ReplaceVehicleTextInContainer(RectTransform container, string backpackTitle)
{
if ((Object)(object)container == (Object)null || string.IsNullOrEmpty(backpackTitle))
{
return;
}
Il2CppArrayBase<Component> componentsInChildren = ((Component)container).GetComponentsInChildren<Component>(true);
for (int i = 0; i < componentsInChildren.Length; i++)
{
Component val = componentsInChildren[i];
if (!((Object)(object)val == (Object)null) && IsTextLikeComponent(val))
{
string text = NormalizeLabelText(GetLabelText(val));
if (text.Equals("Vehicle", StringComparison.OrdinalIgnoreCase))
{
SetLabelText(val, backpackTitle);
}
}
}
}
private static void ReplaceVehicleTextEverywhere(PanelState panel, string backpackTitle)
{
if (panel != null && !string.IsNullOrEmpty(backpackTitle) && (Object)(object)panel.BackpackContainer != (Object)null)
{
ReplaceVehicleTextInContainer(panel.BackpackContainer, backpackTitle);
}
}
private static void UpdateBackpackHeaderTexts(PanelState state)
{
if (state != null)
{
if ((Object)(object)state.OverlayTitleLabel != (Object)null)
{
SetLabelText(state.OverlayTitleLabel, GetBackpackDisplayName());
}
if ((Object)(object)state.OverlaySubtitleLabel != (Object)null)
{
SetLabelText(state.OverlaySubtitleLabel, "Items from your backpack.");
}
}
}
private static void EnsurePagingControls(PanelState state)
{
//IL_0247: Unknown result type (might be due to invalid IL or missing references)
//IL_0283: 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_00d4: Expected O, but got Unknown
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_02bf: 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_0398: 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_036f: Unknown result type (might be due to invalid IL or missing references)
//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0416: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)state.BackpackContainer == (Object)null)
{
return;
}
Transform val = ((Transform)state.BackpackContainer).Find("PackRat_Paging");
if ((Object)(object)val == (Object)null)
{
Transform parent = ((Transform)state.BackpackContainer).parent;
if ((Object)(object)parent != (Object)null)
{
val = parent.Find("PackRat_Paging");
}
}
if ((Object)(object)val != (Object)null && (Object)(object)val.parent != (Object)(object)state.BackpackContainer)
{
val.SetParent((Transform)(object)state.BackpackContainer, false);
}
if ((Object)(object)val == (Object)null)
{
GameObject val2 = new GameObject("PackRat_Paging");
val = val2.transform;
val.SetParent((Transform)(object)state.BackpackContainer, false);
RectTransform val3 = val2.AddComponent<RectTransform>();
val3.pivot = new Vector2(0.5f, 1f);
val3.sizeDelta = new Vector2(176f, 58f);
((Transform)val3).localScale = Vector3.one;
LayoutElement val4 = val2.AddComponent<LayoutElement>();
val4.ignoreLayout = true;
Image val5 = val2.AddComponent<Image>();
((Graphic)val5).color = Color32.op_Implicit(new Color32((byte)16, (byte)16, (byte)16, (byte)185));
((Graphic)val5).raycastTarget = false;
}
EnsurePagingBackground(val);
LayoutElement val6 = null;
try
{
val6 = ((Component)val).GetComponent<LayoutElement>();
}
catch
{
}
if ((Object)(object)val6 == (Object)null)
{
try
{
val6 = ((Component)val).gameObject.AddComponent<LayoutElement>();
}
catch
{
}
}
if ((Object)(object)val6 != (Object)null)
{
val6.ignoreLayout = true;
}
state.PrevButton = FindPagerButton(val, "PackRat_PrevButton");
state.NextButton = FindPagerButton(val, "PackRat_NextButton");
state.ToggleButton = FindPagerButton(val, "PackRat_ViewToggleButton");
state.PageLabel = FindPagerLabel(val);
if ((Object)(object)state.PrevButton == (Object)null)
{
state.PrevButton = CreatePagerButton("<", val, new Vector2(-70f, -1f));
}
if ((Object)(object)state.NextButton == (Object)null)
{
state.NextButton = CreatePagerButton(">", val, new Vector2(70f, -1f));
}
if ((Object)(object)state.ToggleButton == (Object)null)
{
state.ToggleButton = CreateToggleButton("Show Vehicle", val, new Vector2(0f, -30f));
}
if ((Object)(object)state.PageLabel == (Object)null)
{
state.PageLabel = CreatePagerLabel(val, new Vector2(0f, -1f));
}
if ((Object)(object)state.PageLabel != (Object)null && ((Object)state.PageLabel).name != "PackRat_PageLabel")
{
state.PageLabel = null;
}
if ((Object)(object)state.PageLabel == (Object)null)
{
state.PageLabel = CreatePagerLabel(val, new Vector2(0f, -1f));
}
ConfigurePagerButton(state.PrevButton, "<", new Vector2(-70f, -10f));
ConfigurePagerButton(state.NextButton, ">", new Vector2(70f, -10f));
ConfigureToggleButton(state.ToggleButton, state.ShowingVehicle ? "Show Backpack" : "Show Vehicle", new Vector2(0f, -34f));
ConfigurePagerLabel(state.PageLabel, new Vector2(0f, -10f));
RectTransform val7 = null;
try
{
val7 = ((Component)val).GetComponent<RectTransform>();
}
catch
{
}
if ((Object)(object)val7 == (Object)null)
{
try
{
val7 = ((Component)val).gameObject.AddComponent<RectTransform>();
}
catch
{
}
}
state.PagingRoot = val7;
UpdatePagingLayout(state);
if (TryGetGameObject((Component)(object)val, out var gameObject) && TryGetGameObject((Component)(object)state.BackpackContainer, out var gameObject2))
{
SetLayerRecursively(gameObject, gameObject2.layer);
val.SetAsLastSibling();
Canvas val8 = null;
try
{
val8 = ((Component)state.BackpackContainer).GetComponentInParent<Canvas>();
}
catch
{
}
Canvas val9 = null;
try
{
val9 = gameObject.GetComponent<Canvas>();
}
catch
{
}
if ((Object)(object)val9 == (Object)null)
{
try
{
val9 = gameObject.AddComponent<Canvas>();
}
catch
{
}
}
if ((Object)(object)val9 == (Object)null)
{
return;
}
val9.overrideSorting = true;
if ((Object)(object)val8 != (Object)null)
{
val9.sortingLayerID = val8.sortingLayerID;
val9.sortingOrder = val8.sortingOrder + 200;
}
else
{
val9.sortingOrder = 5000;
}
GraphicRaycaster val10 = null;
try
{
val10 = gameObject.GetComponent<GraphicRaycaster>();
}
catch
{
}
if ((Object)(object)val10 == (Object)null)
{
try
{
gameObject.AddComponent<GraphicRaycaster>();
}
catch
{
}
}
}
if (state.PrevAction == null)
{
state.PrevAction = delegate
{
if (state.LastPageInputFrame != Time.frameCount && state.CurrentPage > 0)
{
state.LastPageInputFrame = Time.frameCount;
state.CurrentPage--;
ApplyBackpackPage(state);
}
};
}
if (state.NextAction == null)
{
state.NextAction = delegate
{
if (state.LastPageInputFrame != Time.frameCount)
{
int totalPages = GetTotalPages(state);
if (state.CurrentPage < totalPages - 1)
{
state.LastPageInputFrame = Time.frameCount;
state.CurrentPage++;
ApplyBackpackPage(state);
}
}
};
}
if (state.ToggleAction == null)
{
state.ToggleAction = delegate
{
bool flag = HasNearbyVehicleStorage();
if (!flag)
{
state.ShowingVehicle = false;
}
else
{
state.ShowingVehicle = !state.ShowingVehicle;
}
ApplyVisibleStorageMode(state, flag);
HandoverScreen screen = FindOwningScreen(state);
ApplyPrimaryHeaderForMode(screen, state, state.ShowingVehicle);
if (!state.ShowingVehicle)
{
MelonCoroutines.Start(ReapplyHeaderNextFrame(screen, state));
}
if (!state.ShowingVehicle)
{
ApplyBackpackPage(state);
}
else
{
UpdatePagerControls(state, GetTotalPages(state), flag);
}
};
}
if ((Object)(object)state.PrevButton != (Object)null)
{
EventHelper.RemoveListener(state.PrevAction, (UnityEvent)(object)state.PrevButton.onClick);
EventHelper.AddListener(state.PrevAction, (UnityEvent)(object)state.PrevButton.onClick);
}
if ((Object)(object)state.NextButton != (Object)null)
{
EventHelper.RemoveListener(state.NextAction, (UnityEvent)(object)state.NextButton.onClick);
EventHelper.AddListener(state.NextAction, (UnityEvent)(object)state.NextButton.onClick);
}
if ((Object)(object)state.ToggleButton != (Object)null)
{
EventHelper.RemoveListener(state.ToggleAction, (UnityEvent)(object)state.ToggleButton.onClick);
EventHelper.AddListener(state.ToggleAction, (UnityEvent)(object)state.ToggleButton.onClick);
}
}
private static Button CreatePagerButton(string text, Transform parent, Vector2 anchoredPos)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected O, but got Unknown
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: 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_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Uusing System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using FishNet;
using FishNet.Connection;
using FishNet.Object;
using HarmonyLib;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using PackRat;
using PackRat.Config;
using PackRat.Extensions;
using PackRat.Helpers;
using PackRat.Networking;
using PackRat.Patches;
using PackRat.Shops;
using PackRat.Storage;
using ScheduleOne;
using ScheduleOne.AvatarFramework;
using ScheduleOne.AvatarFramework.Customization;
using ScheduleOne.Core.Items.Framework;
using ScheduleOne.DevUtilities;
using ScheduleOne.Equipping;
using ScheduleOne.ItemFramework;
using ScheduleOne.Levelling;
using ScheduleOne.NPCs;
using ScheduleOne.NPCs.Behaviour;
using ScheduleOne.Networking;
using ScheduleOne.Persistence;
using ScheduleOne.Persistence.Datas;
using ScheduleOne.Persistence.Loaders;
using ScheduleOne.PlayerScripts;
using ScheduleOne.Product;
using ScheduleOne.Product.Packaging;
using ScheduleOne.Storage;
using ScheduleOne.TV;
using ScheduleOne.Tools;
using ScheduleOne.UI;
using ScheduleOne.UI.ATM;
using ScheduleOne.UI.Handover;
using ScheduleOne.UI.Items;
using ScheduleOne.UI.Phone;
using ScheduleOne.UI.Shop;
using ScheduleOne.UI.Stations;
using ScheduleOne.Variables;
using ScheduleOne.Vehicles;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: MelonInfo(typeof(global::PackRat.PackRat), "PackRat", "1.1", "SirTidez", null)]
[assembly: MelonColor(1, 255, 165, 0)]
[assembly: MelonGame("TVGS", "Schedule I")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("PackRat-Mono")]
[assembly: AssemblyConfiguration("Debug Mono")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+af91a4e56e731163b437474798bf5deef32360bd")]
[assembly: AssemblyProduct("PackRat-Mono")]
[assembly: AssemblyTitle("PackRat-Mono")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 PackRat
{
public static class BuildInfo
{
public const string Name = "PackRat";
public const string Description = "Portable backpack storage for Schedule One";
public const string Author = "SirTidez";
public const string Version = "1.1";
}
public class PackRat : MelonMod
{
public override void OnInitializeMelon()
{
Configuration.Instance.Load();
ModLogger.Info("PackRat initialized.");
}
public override void OnSceneWasLoaded(int buildIndex, string sceneName)
{
Configuration.Instance.Reset();
if (!(sceneName != "Main"))
{
ConfigSyncManager.StartSync();
BackpackShopIntegration.RunWhenReady();
}
}
}
public class PlayerBackpack : MonoBehaviour
{
[CompilerGenerated]
private sealed class <DeferredConfigureStorage>d__32 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public PlayerBackpack instance;
public int slotCount;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DeferredConfigureStorage>d__32(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = null;
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if ((Object)(object)instance == (Object)null || (Object)(object)instance._storage == (Object)null)
{
return false;
}
instance.UpdateSize(slotCount);
instance.OnStartClient(isOwner: true);
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public const string StorageName = "Backpack";
public const int MaxStorageSlots = 40;
private bool _backpackEnabled = true;
private StorageEntity _storage;
private int _lastTierIndex = -2;
private string _openTitle;
private int _equippedTierIndex = -1;
private const int TierCheckIntervalFrames = 60;
public static PlayerBackpack Instance { get; private set; }
public int EquippedTierIndex => _equippedTierIndex;
public int HighestPurchasedTierIndex => EquippedTierIndex;
public int CurrentTierIndex
{
get
{
Configuration instance = Configuration.Instance;
if (_equippedTierIndex < 0)
{
return -1;
}
for (int num = _equippedTierIndex; num >= 0; num--)
{
if (num < instance.TierEnabled.Length && instance.TierEnabled[num])
{
return num;
}
}
return -1;
}
}
public BackpackTierDefinition CurrentTier
{
get
{
int currentTierIndex = CurrentTierIndex;
return (currentTierIndex >= 0) ? Configuration.BackpackTiers[currentTierIndex] : null;
}
}
public bool IsUnlocked => CurrentTierIndex >= 0;
public bool IsPoliceSearchable => CurrentTierIndex >= 2;
public bool IsOpen => Singleton<StorageMenu>.Instance.IsOpen && ((TMP_Text)Singleton<StorageMenu>.Instance.TitleLabel).text == _openTitle;
public List<ItemSlot> ItemSlots => _storage.ItemSlots.ToList();
public void SetEquippedTierIndex(int tierIndex)
{
_equippedTierIndex = ((tierIndex < 0) ? (-1) : Math.Min(tierIndex, Configuration.BackpackTiers.Length - 1));
}
public void SetHighestPurchasedTierIndex(int tierIndex)
{
SetEquippedTierIndex(tierIndex);
}
public void RestorePurchasedTier(int tierIndex)
{
SetEquippedTierIndex(tierIndex);
EnsureCorrectTierApplied();
}
private void Awake()
{
_storage = ((Component)this).gameObject.GetComponentInParent<StorageEntity>();
if ((Object)(object)_storage == (Object)null)
{
ModLogger.Error("Player does not have a BackpackStorage component!");
return;
}
ModLogger.Info("Configuring backpack storage...");
int currentTierIndex = CurrentTierIndex;
int slotCount = ((currentTierIndex >= 0) ? Configuration.Instance.TierSlotCounts[currentTierIndex] : Configuration.BackpackTiers[0].DefaultSlotCount);
MelonCoroutines.Start(DeferredConfigureStorage(this, slotCount));
}
[IteratorStateMachine(typeof(<DeferredConfigureStorage>d__32))]
private static IEnumerator DeferredConfigureStorage(PlayerBackpack instance, int slotCount)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DeferredConfigureStorage>d__32(0)
{
instance = instance,
slotCount = slotCount
};
}
private void Update()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
bool keyDown = Input.GetKeyDown(Configuration.Instance.ToggleKey);
if (keyDown || Time.frameCount % 60 == 0)
{
int currentTierIndex = CurrentTierIndex;
if (currentTierIndex != _lastTierIndex)
{
_lastTierIndex = currentTierIndex;
ApplyCurrentTier(currentTierIndex);
}
}
if (!_backpackEnabled || !keyDown)
{
return;
}
try
{
if (TryConsumeSelectedHotbarBackpackItem(out var appliedTier))
{
if (appliedTier >= 0)
{
ModLogger.Info($"Backpack tier {appliedTier} ({Configuration.BackpackTiers[appliedTier].Name}) applied; opening backpack.");
}
if (IsOpen)
{
Close();
}
else
{
Open();
}
}
else if (IsUnlocked)
{
if (IsOpen)
{
Close();
}
else
{
Open();
}
}
}
catch (Exception exception)
{
ModLogger.Error("Error toggling backpack", exception);
}
}
private bool TryConsumeSelectedHotbarBackpackItem(out int appliedTier)
{
appliedTier = -1;
try
{
PlayerInventory instance = PlayerSingleton<PlayerInventory>.Instance;
if ((Object)(object)instance == (Object)null)
{
return false;
}
object obj = ReflectionUtils.TryGetFieldOrProperty(instance, "hotbarSlots");
if (obj == null)
{
return false;
}
int num = ReflectionUtils.TryGetListCount(obj);
if (num <= 0)
{
return false;
}
int selectedHotbarIndex = GetSelectedHotbarIndex(instance);
if (selectedHotbarIndex >= 0 && selectedHotbarIndex < num && TryConsumeBackpackItemFromSlot(instance, obj, selectedHotbarIndex, out appliedTier))
{
return true;
}
for (int i = 0; i < num; i++)
{
if (TryConsumeBackpackItemFromSlot(instance, obj, i, out appliedTier))
{
return true;
}
}
List<object> list = ReflectionUtils.TryGetAllListLikeMembers(instance);
foreach (object item in list)
{
if (item == obj)
{
continue;
}
int num2 = ReflectionUtils.TryGetListCount(item);
for (int j = 0; j < num2; j++)
{
if (TryConsumeBackpackItemFromSlot(instance, item, j, out appliedTier))
{
return true;
}
}
}
return false;
}
catch (Exception exception)
{
ModLogger.Error("TryConsumeSelectedHotbarBackpackItem", exception);
return false;
}
}
private bool TryConsumeBackpackItemFromSlot(object playerInventory, object slotsList, int index, out int appliedTier)
{
appliedTier = -1;
object obj = ReflectionUtils.TryGetListItem(slotsList, index);
if (obj == null)
{
return false;
}
object obj2 = ReflectionUtils.TryGetFieldOrProperty(obj, "ItemInstance");
if (obj2 == null)
{
return false;
}
object obj3 = ReflectionUtils.TryGetFieldOrProperty(obj2, "Definition");
if (obj3 == null)
{
return false;
}
object obj4 = ReflectionUtils.TryGetFieldOrProperty(obj3, "ID") ?? ReflectionUtils.TryGetFieldOrProperty(obj3, "id");
string text = (obj4 as string) ?? obj4?.ToString();
if (string.IsNullOrEmpty(text) || !text.StartsWith("PackRat_Backpack_Tier_", StringComparison.Ordinal))
{
return false;
}
if (!BackpackShopIntegration.IsBackpackTierPurchase(text, out var tierIndex) || tierIndex < 0)
{
return false;
}
ClearSlotItem(obj);
RefreshInventoryUIAfterSlotChange(playerInventory, obj);
if (tierIndex != _equippedTierIndex)
{
SetEquippedTierIndex(tierIndex);
ApplyTierAfterPurchase(tierIndex);
BackpackShopIntegration.RefreshBackpackListingsInAllShops();
appliedTier = tierIndex;
}
return true;
}
private static int GetSelectedHotbarIndex(object playerInventory)
{
if (playerInventory == null)
{
return -1;
}
string[] array = new string[16]
{
"selectedSlotIndex", "SelectedSlotIndex", "selectedIndex", "SelectedIndex", "currentSlotIndex", "CurrentSlotIndex", "activeSlotIndex", "ActiveSlotIndex", "activeIndex", "ActiveIndex",
"equippedSlotIndex", "EquippedSlotIndex", "SelectedSlot", "selectedSlot", "slotIndex", "SlotIndex"
};
foreach (string memberName in array)
{
object obj = ReflectionUtils.TryGetFieldOrProperty(playerInventory, memberName);
if (obj != null)
{
if (obj is int num && num >= 0)
{
return num;
}
if (obj is byte result)
{
return result;
}
if (obj is short num2 && num2 >= 0)
{
return num2;
}
if (obj is long num3 && num3 >= 0 && num3 <= int.MaxValue)
{
return (int)num3;
}
}
}
return -1;
}
private static void ClearSlotItem(object slot)
{
if (slot == null)
{
return;
}
Type type = slot.GetType();
MethodInfo methodInfo = ReflectionUtils.GetMethod(type, "ClearStoredInstance", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? ReflectionUtils.GetMethod(type, "Clear", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic) ?? ReflectionUtils.GetMethod(type, "ClearSlot", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (methodInfo != null)
{
try
{
methodInfo.Invoke(slot, null);
return;
}
catch
{
}
}
ReflectionUtils.TrySetFieldOrProperty(slot, "ItemInstance", null);
}
private static void RefreshInventoryUIAfterSlotChange(object playerInventory, object slotThatChanged)
{
if (slotThatChanged != null)
{
ReflectionUtils.TryInvokeParameterlessCallback(slotThatChanged, "onItemDataChanged", "OnItemDataChanged", "ItemDataChanged");
}
if (playerInventory != null)
{
ReflectionUtils.TryInvokeParameterlessCallback(playerInventory, "Refresh", "RefreshUI", "UpdateDisplay", "OnInventoryChanged", "NotifySlotsChanged", "Rebuild");
}
}
private void ApplyCurrentTier(int tierIdx)
{
if (tierIdx >= 0)
{
int num = Configuration.Instance.TierSlotCounts[tierIdx];
if (_storage.SlotCount != num)
{
ModLogger.Info($"Backpack upgraded to {Configuration.BackpackTiers[tierIdx].Name} ({num} slots).");
UpdateSize(num);
}
}
}
public void ApplyTierAfterPurchase(int tierIdx)
{
if (tierIdx >= 0)
{
_lastTierIndex = tierIdx;
ApplyCurrentTier(tierIdx);
}
}
public void EnsureCorrectTierApplied()
{
_lastTierIndex = CurrentTierIndex;
if (!((Object)(object)_storage == (Object)null) && _lastTierIndex >= 0)
{
ApplyCurrentTier(_lastTierIndex);
}
}
public void SetBackpackEnabled(bool state)
{
if (!state)
{
Close();
}
_backpackEnabled = state;
}
public void Open()
{
if (!_backpackEnabled)
{
ModLogger.Debug("Backpack open blocked: backpack disabled.");
}
else if (!IsUnlocked)
{
ModLogger.Debug($"Backpack open blocked: not unlocked (CurrentTierIndex={CurrentTierIndex}, EquippedTier={_equippedTierIndex}). Purchase a tier at the Hardware Store.");
}
else if ((Object)(object)_storage == (Object)null)
{
ModLogger.Warn("Backpack open blocked: no storage entity.");
}
else if (!Singleton<ManagementClipboard>.Instance.IsEquipped && !Singleton<StorageMenu>.Instance.IsOpen && !PlayerSingleton<Phone>.Instance.IsOpen)
{
if (CameraLockedStateHelper.IsCameraLockedByUI())
{
ModLogger.Debug("Backpack blocked: player is in camera-locked UI (TV, ATM, dialogue, vehicle, etc.).");
return;
}
_openTitle = CurrentTier?.Name ?? "Backpack";
StorageMenu instance = Singleton<StorageMenu>.Instance;
instance.SlotGridLayout.constraintCount = _storage.DisplayRowCount;
instance.Open(_openTitle, string.Empty, (IItemSlotOwner)(object)_storage);
_storage.SendAccessor(((NetworkBehaviour)Player.Local).NetworkObject);
}
}
public void Close()
{
if (_backpackEnabled && IsOpen)
{
Singleton<StorageMenu>.Instance.CloseMenu();
_storage.SendAccessor((NetworkObject)null);
}
}
public bool ContainsItemsOfInterest(EStealthLevel maxStealthLevel)
{
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
for (int i = 0; i < _storage.ItemSlots.Count; i++)
{
ItemSlot val = _storage.ItemSlots[i];
if (((val != null) ? val.ItemInstance : null) == null)
{
continue;
}
ItemInstance itemInstance = val.ItemInstance;
ProductItemInstance val2 = (ProductItemInstance)(object)((itemInstance is ProductItemInstance) ? itemInstance : null);
if (val2 == null)
{
string a = (ReflectionUtils.TryGetFieldOrProperty(val.ItemInstance.Definition, "legalStatus") ?? ReflectionUtils.TryGetFieldOrProperty(val.ItemInstance.Definition, "LegalStatus"))?.ToString();
if (!string.Equals(a, "Legal", StringComparison.Ordinal))
{
return true;
}
}
else if ((Object)(object)val2.AppliedPackaging == (Object)null || val2.AppliedPackaging.StealthLevel <= maxStealthLevel)
{
return true;
}
}
return false;
}
public void Upgrade(int slotCount)
{
if ((slotCount >= 1 && slotCount <= 40) || 1 == 0)
{
int num = _storage.SlotCount + slotCount;
if (num > 40)
{
ModLogger.Warn($"Cannot upgrade backpack to more than {40} slots.");
}
else
{
UpdateSize(num);
}
}
}
public void Downgrade(int slotCount, bool force = false)
{
if (slotCount < 1)
{
return;
}
if (!force && slotCount >= _storage.SlotCount)
{
ModLogger.Warn("Cannot downgrade backpack to zero slots. A minimum of one must remain.");
return;
}
int num = _storage.SlotCount - slotCount;
if (num < 1)
{
num = 1;
}
if (force)
{
UpdateSize(num);
return;
}
bool flag = true;
List<ItemSlot> range = _storage.ItemSlots.GetRange(num, _storage.SlotCount - num);
for (int i = 0; i < range.Count; i++)
{
List<ItemSlot> list = range;
ItemSlot val = list[new Index(i).GetOffset(list.Count)];
if (((val != null) ? val.ItemInstance : null) != null)
{
ModLogger.Warn("Downgrading backpack will remove item: " + ((Object)val.ItemInstance.Definition).name);
flag = false;
}
}
if (!flag)
{
ModLogger.Warn("Cannot downgrade backpack due to items present in removed slots.");
}
else
{
UpdateSize(num);
}
}
private void UpdateSize(int newSize)
{
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00cd: Expected O, but got Unknown
_storage.SlotCount = newSize;
StorageEntity storage = _storage;
if (1 == 0)
{
}
int displayRowCount = ((newSize <= 20) ? ((int)Math.Ceiling((double)newSize / 5.0)) : ((newSize > 80) ? ((int)Math.Ceiling((double)newSize / 16.0)) : ((int)Math.Ceiling((double)newSize / 10.0))));
if (1 == 0)
{
}
storage.DisplayRowCount = displayRowCount;
if (_storage.ItemSlots.Count > newSize)
{
_storage.ItemSlots.RemoveRange(newSize, _storage.ItemSlots.Count - newSize);
return;
}
for (int i = _storage.ItemSlots.Count; i < newSize; i++)
{
ItemSlot val = new ItemSlot();
int count = _storage.ItemSlots.Count;
val.onItemDataChanged = (Action)Delegate.Combine(val.onItemDataChanged, new Action(_storage.ContentsChanged));
val.SetSlotOwner((IItemSlotOwner)(object)_storage);
if (_storage.ItemSlots.Count == count)
{
_storage.ItemSlots.Add(val);
}
}
}
private void OnStartClient(bool isOwner)
{
if (!isOwner)
{
ModLogger.Info("Destroying non-local player backpack on: " + ((Object)this).name);
Object.Destroy((Object)(object)this);
}
else if ((Object)(object)Instance != (Object)null)
{
ModLogger.Warn("Multiple instances of " + ((Object)this).name + " exist. Keeping prior instance reference.");
Object.Destroy((Object)(object)this);
}
else
{
Instance = this;
CameraLockedStateHelper.PrewarmCache();
}
}
private void OnDestroy()
{
if ((Object)(object)Instance == (Object)(object)this)
{
Instance = null;
}
}
}
}
namespace PackRat.Storage
{
public sealed class BackpackSaveData
{
public string Contents { get; set; }
public int EquippedTierIndex { get; set; } = -1;
public int HighestPurchasedTierIndex { get; set; } = -1;
}
}
namespace PackRat.Shops
{
public static class BackpackShopIntegration
{
[CompilerGenerated]
private sealed class <WaitAndIntegrate>d__10 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
private int <i>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <WaitAndIntegrate>d__10(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<i>5__1 = 0;
break;
case 1:
<>1__state = -1;
AddToAllHardwareStoresInScene();
<i>5__1++;
break;
}
if (<i>5__1 < 60)
{
<>2__current = (object)new WaitForSeconds(0.5f);
<>1__state = 1;
return true;
}
if (_shopsIntegrated.Count == 0)
{
LogHardwareStoreNotFound();
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public const string BackpackItemIdPrefix = "PackRat_Backpack_Tier_";
private const string HardwareStoreName = "Hardware Store";
private static readonly string[] TierDescriptions = new string[5] { "A basic 8-slot backpack. Good for starting out.", "A compact 16-slot pack. Stays under the radar.", "24 slots. Police may search this size and above.", "32 slots. Sturdy and roomy; draws more attention.", "The largest option with 40 slots. Maximum capacity." };
private static readonly HashSet<int> _shopsIntegrated = new HashSet<int>();
private static StorableItemDefinition _safeBackpackTemplate;
private static bool _loggedSafeTemplateUnavailable;
private static bool _loggedBackpackDefinitionCreationFailure;
private static bool _loggedListingIntegrationFailureSummary;
public static void RunWhenReady()
{
MelonCoroutines.Start(WaitAndIntegrate());
}
public static bool TryAddBackpackListingsToShop(ShopInterface shop)
{
if ((Object)(object)shop == (Object)null)
{
return false;
}
if (!TryMatchHardwareStore(shop, out var _))
{
return false;
}
int instanceID = ((Object)shop).GetInstanceID();
bool flag = _shopsIntegrated.Add(instanceID);
if (AddBackpackListings(shop))
{
if (flag)
{
ModLogger.Info($"BackpackShopIntegration: Added backpack tier listings to Hardware Store (instance {instanceID}).");
}
return true;
}
ModLogger.Warn("BackpackShopIntegration: Hardware Store found but adding listings failed (see tier warnings above).");
return false;
}
[IteratorStateMachine(typeof(<WaitAndIntegrate>d__10))]
private static IEnumerator WaitAndIntegrate()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <WaitAndIntegrate>d__10(0);
}
private static void AddToAllHardwareStoresInScene()
{
try
{
Type typeFromHandle = typeof(ShopInterface);
FieldInfo field = typeFromHandle.GetField("AllShops", BindingFlags.Static | BindingFlags.Public);
if (field != null && field.GetValue(null) is IEnumerable enumerable)
{
foreach (object item in enumerable)
{
if (item != null && TryMatchHardwareStore(item, out var shop))
{
TryAddBackpackListingsToShop(shop);
}
}
}
ShopInterface[] array = Utils.FindObjectsOfTypeSafe<ShopInterface>();
if (array == null)
{
return;
}
for (int i = 0; i < array.Length; i++)
{
if ((Object)(object)array[i] != (Object)null && TryMatchHardwareStore(array[i], out var shop2))
{
TryAddBackpackListingsToShop(shop2);
}
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: AddToAllHardwareStoresInScene", exception);
}
}
private static void LogHardwareStoreNotFound()
{
List<string> list = new List<string>();
try
{
Type typeFromHandle = typeof(ShopInterface);
FieldInfo field = typeFromHandle.GetField("AllShops", BindingFlags.Static | BindingFlags.Public);
if (field != null)
{
object value = field.GetValue(null);
if (value != null && value is IEnumerable enumerable)
{
foreach (object item in enumerable)
{
if (item != null)
{
string shopDisplayName = GetShopDisplayName(item);
if (!string.IsNullOrEmpty(shopDisplayName) && !list.Contains(shopDisplayName))
{
list.Add(shopDisplayName);
}
}
}
}
}
if (list.Count == 0)
{
ShopInterface[] array = Utils.FindObjectsOfTypeSafe<ShopInterface>();
if (array != null)
{
for (int i = 0; i < array.Length; i++)
{
string shopDisplayName2 = GetShopDisplayName(array[i]);
if (!string.IsNullOrEmpty(shopDisplayName2) && !list.Contains(shopDisplayName2))
{
list.Add(shopDisplayName2);
}
}
}
}
}
catch
{
}
if (list.Count > 0)
{
ModLogger.Warn("BackpackShopIntegration: Hardware Store not found after 30s. Shop names in game: [" + string.Join(", ", list) + "]. If your hardware store uses a different name, we can add a match for it.");
}
else
{
ModLogger.Warn("BackpackShopIntegration: Hardware Store not found after 30s (no ShopInterface instances with a name found). Shops may load later when you open them.");
}
}
private static bool TryGetHardwareStore(out ShopInterface shop)
{
shop = null;
try
{
Type typeFromHandle = typeof(ShopInterface);
FieldInfo field = typeFromHandle.GetField("AllShops", BindingFlags.Static | BindingFlags.Public);
if (field != null)
{
object value = field.GetValue(null);
if (value != null && value is IEnumerable enumerable)
{
int num = 0;
foreach (object item in enumerable)
{
if (item != null)
{
num++;
if (TryMatchHardwareStore(item, out shop))
{
return true;
}
}
}
}
}
ShopInterface[] array = Utils.FindObjectsOfTypeSafe<ShopInterface>();
if (array != null && array.Length != 0)
{
foreach (ShopInterface val in array)
{
if (!((Object)(object)val == (Object)null) && TryMatchHardwareStore(val, out shop))
{
return true;
}
}
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: Error finding Hardware Store", exception);
}
return false;
}
private static bool TryMatchHardwareStore(object shopObj, out ShopInterface shop)
{
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Expected O, but got Unknown
shop = null;
if (shopObj == null)
{
return false;
}
string shopDisplayName = GetShopDisplayName(shopObj);
if (string.IsNullOrEmpty(shopDisplayName))
{
return false;
}
if (!string.Equals(shopDisplayName, "Hardware Store", StringComparison.OrdinalIgnoreCase) && shopDisplayName.IndexOf("Hardware", StringComparison.OrdinalIgnoreCase) < 0)
{
return false;
}
try
{
shop = (ShopInterface)shopObj;
return true;
}
catch
{
return false;
}
}
private static string GetShopDisplayName(object shopObj)
{
if (shopObj == null)
{
return null;
}
string[] array = new string[5] { "ShopName", "shopName", "Name", "name", "DisplayName" };
foreach (string memberName in array)
{
object obj = ReflectionUtils.TryGetFieldOrProperty(shopObj, memberName);
if (obj is string text && !string.IsNullOrWhiteSpace(text))
{
return text.Trim();
}
}
return null;
}
private static bool AddBackpackListings(ShopInterface shop)
{
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Expected O, but got Unknown
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_0070: 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_008c: 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_00c2: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)shop == (Object)null)
{
return false;
}
if (shop.Listings == null)
{
ModLogger.Warn("BackpackShopIntegration: Shop.Listings is null; cannot add backpack listings.");
return false;
}
Configuration instance = Configuration.Instance;
if (!LevelManagerPatch.TryGetFallbackIcon(out var texture, out var sprite))
{
texture = new Texture2D(2, 2);
texture.SetPixel(0, 0, Color.white);
texture.SetPixel(1, 0, Color.white);
texture.SetPixel(0, 1, Color.white);
texture.SetPixel(1, 1, Color.white);
texture.Apply();
sprite = Sprite.Create(texture, new Rect(0f, 0f, 2f, 2f), new Vector2(0.5f, 0.5f));
ModLogger.Warn("BackpackShopIntegration: Fallback icon resource missing; using generated placeholder icon.");
}
int num = (((Object)(object)PlayerBackpack.Instance != (Object)null) ? PlayerBackpack.Instance.EquippedTierIndex : (-1));
bool flag = false;
bool flag2 = false;
bool flag3 = false;
int num2 = 0;
int num3 = 0;
int num4 = 0;
for (int i = 0; i < Configuration.BackpackTiers.Length; i++)
{
if (!instance.TierEnabled[i])
{
RemoveTierListingFromShop(shop, "PackRat_Backpack_Tier_" + i);
continue;
}
flag2 = true;
string itemId = "PackRat_Backpack_Tier_" + i;
if (i == num)
{
RemoveTierListingFromShop(shop, itemId);
continue;
}
if (ShopHasItem(shop, itemId))
{
flag3 = true;
continue;
}
Sprite tierSprite = LevelManagerPatch.GetTierSprite(i, sprite, texture);
StorableItemDefinition val = GetRegisteredBackpackDefinition(itemId);
if ((Object)(object)val != (Object)null)
{
ConfigureBackpackTierDefinition(val, i, itemId, instance, tierSprite);
}
else
{
val = CreateBackpackTierDefinition(shop, i, itemId, instance, tierSprite);
}
if ((Object)(object)val == (Object)null)
{
num2++;
}
else if ((Object)(object)GetRegisteredBackpackDefinition(itemId) == (Object)null && !RegisterDefinition(val))
{
num3++;
ModLogger.Warn($"BackpackShopIntegration: Could not register definition for tier {i}.");
}
else if (!AddListingToShop(shop, val, sprite, texture))
{
num4++;
ModLogger.Warn($"BackpackShopIntegration: Could not add listing for tier {i}.");
}
else
{
flag = true;
}
}
if (flag)
{
_loggedListingIntegrationFailureSummary = false;
ModLogger.Info("BackpackShopIntegration: Added backpack tier listings to Hardware Store.");
}
if (!flag2 || flag3 || flag)
{
_loggedListingIntegrationFailureSummary = false;
return true;
}
if (!_loggedListingIntegrationFailureSummary)
{
_loggedListingIntegrationFailureSummary = true;
ModLogger.Warn($"BackpackShopIntegration: Eligible tiers found but none added. missingDef={num2}, registerFailed={num3}, listingFailed={num4}");
}
return false;
}
public static void RefreshBackpackListingsInAllShops()
{
AddToAllHardwareStoresInScene();
}
private static bool ShopHasItem(ShopInterface shop, string itemId)
{
try
{
if (shop.Listings == null)
{
return false;
}
foreach (ShopListing listing in shop.Listings)
{
if ((Object)(object)listing?.Item != (Object)null && ((BaseItemDefinition)listing.Item).ID == itemId)
{
return true;
}
}
}
catch
{
}
return false;
}
private static StorableItemDefinition CreateBackpackTierDefinition(ShopInterface shop, int tierIndex, string itemId, Configuration cfg, Sprite iconSprite)
{
try
{
StorableItemDefinition val = CreateEmptyStorableItemDefinition();
if ((Object)(object)val == (Object)null)
{
val = CloneSafeBackpackTemplate(shop);
}
if ((Object)(object)val == (Object)null && !_loggedBackpackDefinitionCreationFailure)
{
_loggedBackpackDefinitionCreationFailure = true;
ModLogger.Warn("BackpackShopIntegration: Could not create a backpack item definition. Skipping backpack listings until a valid template can be created.");
}
if ((Object)(object)val == (Object)null)
{
return null;
}
ConfigureBackpackTierDefinition(val, tierIndex, itemId, cfg, iconSprite);
return val;
}
catch (Exception exception)
{
ModLogger.Error($"BackpackShopIntegration: CreateBackpackTierDefinition tier {tierIndex}", exception);
return null;
}
}
private static void ConfigureBackpackTierDefinition(StorableItemDefinition def, int tierIndex, string itemId, Configuration cfg, Sprite iconSprite)
{
//IL_0140: 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_0145: Unknown result type (might be due to invalid IL or missing references)
//IL_014c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)def == (Object)null)
{
return;
}
ApplyBackpackDefinitionDefaults(def);
if (!ReflectionUtils.TrySetFieldOrProperty(def, "ID", itemId))
{
ReflectionUtils.TrySetFieldOrProperty(def, "id", itemId);
}
string name = Configuration.BackpackTiers[tierIndex].Name;
if (!ReflectionUtils.TrySetFieldOrProperty(def, "Name", name))
{
ReflectionUtils.TrySetFieldOrProperty(def, "name", name);
}
if ((Object)(object)iconSprite != (Object)null)
{
string[] array = new string[7] { "Icon", "icon", "Sprite", "sprite", "ItemIcon", "itemIcon", "DisplayIcon" };
foreach (string memberName in array)
{
if (ReflectionUtils.TrySetFieldOrProperty(def, memberName, iconSprite))
{
break;
}
}
}
float num = ((tierIndex < cfg.TierPrices.Length) ? cfg.TierPrices[tierIndex] : (25f + (float)tierIndex * 50f));
ReflectionUtils.TrySetFieldOrProperty(def, "BasePurchasePrice", num);
FullRank val = ((tierIndex < cfg.TierUnlockRanks.Length) ? cfg.TierUnlockRanks[tierIndex] : Configuration.BackpackTiers[tierIndex].DefaultUnlockRank);
ReflectionUtils.TrySetFieldOrProperty(def, "RequiredRank", val);
ReflectionUtils.TrySetFieldOrProperty(def, "RequiresLevelToPurchase", true);
string value = ((tierIndex < TierDescriptions.Length) ? TierDescriptions[tierIndex] : null);
if (string.IsNullOrEmpty(value))
{
return;
}
string[] array2 = new string[8] { "Description", "description", "TooltipText", "tooltipText", "FlavorText", "flavorText", "ItemDescription", "itemDescription" };
foreach (string memberName2 in array2)
{
if (ReflectionUtils.TrySetFieldOrProperty(def, memberName2, value))
{
break;
}
}
}
private static StorableItemDefinition GetRegisteredBackpackDefinition(string itemId)
{
if (string.IsNullOrWhiteSpace(itemId))
{
return null;
}
try
{
ItemDefinition registeredItemDefinition = GetRegisteredItemDefinition(itemId);
if ((Object)(object)registeredItemDefinition == (Object)null)
{
return null;
}
return (StorableItemDefinition)(object)((registeredItemDefinition is StorableItemDefinition) ? registeredItemDefinition : null);
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: GetRegisteredBackpackDefinition", exception);
return null;
}
}
private static ItemDefinition GetRegisteredItemDefinition(string itemId)
{
if (string.IsNullOrWhiteSpace(itemId))
{
return null;
}
try
{
if (Registry.ItemExists(itemId))
{
return Registry.GetItem(itemId);
}
}
catch
{
}
try
{
Registry instance = Singleton<Registry>.Instance;
if ((Object)(object)instance == (Object)null)
{
return null;
}
ItemDefinition val = FindDefinitionInRegistryList(instance.ItemRegistry, itemId);
if ((Object)(object)val != (Object)null)
{
return val;
}
return FindDefinitionInRegistryList(instance.ItemsAddedAtRuntime, itemId);
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: GetRegisteredItemDefinition", exception);
return null;
}
}
private static ItemDefinition FindDefinitionInRegistryList(IEnumerable registryList, string itemId)
{
if (registryList == null || string.IsNullOrWhiteSpace(itemId))
{
return null;
}
foreach (object registry in registryList)
{
if (registry != null)
{
string a = ReflectionUtils.TryGetFieldOrProperty(registry, "ID") as string;
if (string.Equals(a, itemId, StringComparison.OrdinalIgnoreCase))
{
object obj = ReflectionUtils.TryGetFieldOrProperty(registry, "Definition");
return (ItemDefinition)((obj is ItemDefinition) ? obj : null);
}
}
}
return null;
}
private static StorableItemDefinition CloneTemplateStorableItemDefinition(ShopInterface shop)
{
if (shop?.Listings == null)
{
return null;
}
try
{
foreach (ShopListing listing in shop.Listings)
{
if (!((Object)(object)listing?.Item == (Object)null))
{
StorableItemDefinition item = listing.Item;
if (!((Object)(object)item == (Object)null))
{
return Object.Instantiate<StorableItemDefinition>(item);
}
}
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: CloneTemplateStorableItemDefinition", exception);
}
return null;
}
private static StorableItemDefinition CloneSafeBackpackTemplate(ShopInterface shop)
{
if ((Object)(object)_safeBackpackTemplate == (Object)null)
{
_safeBackpackTemplate = CreateSafeBackpackTemplate(shop);
if ((Object)(object)_safeBackpackTemplate == (Object)null)
{
if (!_loggedSafeTemplateUnavailable)
{
_loggedSafeTemplateUnavailable = true;
ModLogger.Warn("BackpackShopIntegration: Safe backpack template is unavailable in IL2CPP. Backpack listings will retry once the shop can provide a valid storable-item template.");
}
return null;
}
}
try
{
return Object.Instantiate<StorableItemDefinition>(_safeBackpackTemplate);
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: CloneSafeBackpackTemplate", exception);
return null;
}
}
public static StorableItemDefinition CreateSafeBackpackTemplate(ShopInterface shop = null)
{
if ((Object)(object)_safeBackpackTemplate != (Object)null)
{
return _safeBackpackTemplate;
}
try
{
_safeBackpackTemplate = CreateEmptyStorableItemDefinition();
if ((Object)(object)_safeBackpackTemplate == (Object)null && (Object)(object)shop != (Object)null)
{
_safeBackpackTemplate = CloneTemplateStorableItemDefinition(shop);
}
if ((Object)(object)_safeBackpackTemplate == (Object)null)
{
if (!_loggedSafeTemplateUnavailable)
{
_loggedSafeTemplateUnavailable = true;
ModLogger.Warn("BackpackShopIntegration: Could not create safe backpack template instance yet.");
}
return null;
}
ApplyBackpackDefinitionDefaults(_safeBackpackTemplate);
ReflectionUtils.TrySetFieldOrProperty(_safeBackpackTemplate, "ID", "PackRat_Template");
ReflectionUtils.TrySetFieldOrProperty(_safeBackpackTemplate, "Name", "Backpack");
ReflectionUtils.TrySetFieldOrProperty(_safeBackpackTemplate, "BasePurchasePrice", 0f);
ReflectionUtils.TrySetFieldOrProperty(_safeBackpackTemplate, "RequiredRank", 0);
ReflectionUtils.TrySetFieldOrProperty(_safeBackpackTemplate, "RequiresLevelToPurchase", false);
ReflectionUtils.TrySetFieldOrProperty(_safeBackpackTemplate, "Description", string.Empty);
_loggedSafeTemplateUnavailable = false;
_loggedBackpackDefinitionCreationFailure = false;
_loggedListingIntegrationFailureSummary = false;
ModLogger.Info("BackpackShopIntegration: Safe backpack template created successfully.");
return _safeBackpackTemplate;
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: CreateSafeBackpackTemplate", exception);
return null;
}
}
private static void ApplyBackpackDefinitionDefaults(StorableItemDefinition def)
{
if (!((Object)(object)def == (Object)null))
{
ReflectionUtils.TrySetFieldOrProperty(def, "Description", string.Empty);
ReflectionUtils.TrySetEnumFieldOrProperty(def, "Category", "Storage");
ReflectionUtils.TrySetFieldOrProperty(def, "StoredItem", null);
ReflectionUtils.TrySetFieldOrProperty(def, "StationItem", null);
ReflectionUtils.TrySetFieldOrProperty(def, "Equippable", null);
ReflectionUtils.TrySetFieldOrProperty(def, "CustomItemUI", null);
ReflectionUtils.TrySetFieldOrProperty(def, "CustomInfoContent", null);
ReflectionUtils.TrySetEnumFieldOrProperty(def, "legalStatus", "Legal");
ReflectionUtils.TrySetFieldOrProperty(def, "ResellMultiplier", 0.5f);
ReflectionUtils.TrySetFieldOrProperty(def, "PickpocketDifficultyMultiplier", 1f);
ReflectionUtils.TrySetFieldOrProperty(def, "CombatUtility", 0f);
}
}
private static StorableItemDefinition CreateEmptyStorableItemDefinition()
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
try
{
return (StorableItemDefinition)ScriptableObject.CreateInstance(typeof(StorableItemDefinition));
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: CreateEmptyStorableItemDefinition", exception);
return null;
}
}
private static bool RegisterDefinition(StorableItemDefinition def)
{
try
{
if ((Object)(object)def == (Object)null || string.IsNullOrWhiteSpace(((BaseItemDefinition)def).ID))
{
return false;
}
if ((Object)(object)GetRegisteredItemDefinition(((BaseItemDefinition)def).ID) != (Object)null)
{
ModLogger.Debug("BackpackShopIntegration: Definition '" + ((BaseItemDefinition)def).ID + "' is already registered; reusing existing definition.");
return true;
}
Registry instance = Singleton<Registry>.Instance;
if ((Object)(object)instance == (Object)null)
{
return false;
}
MethodInfo method = ((object)instance).GetType().GetMethod("AddToRegistry", BindingFlags.Instance | BindingFlags.Public);
if (method == null)
{
return false;
}
method.Invoke(instance, new object[1] { def });
return true;
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: RegisterDefinition", exception);
return false;
}
}
private static bool AddListingToShop(ShopInterface shop, StorableItemDefinition def, Sprite fallbackSprite, Texture2D fallbackTexture)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Expected O, but got Unknown
try
{
ShopListing val = new ShopListing
{
Item = def,
name = ((BaseItemDefinition)def).Name
};
shop.Listings.Add(val);
val.Initialize(shop);
if (!TryInvokeShopMethod(shop, "CreateListingUI", val))
{
Sprite tierSprite = LevelManagerPatch.GetTierSprite(ParseTierFromItemId(((BaseItemDefinition)def).ID), fallbackSprite, fallbackTexture);
CreateListingUI(shop, val, tierSprite);
}
TryInvokeShopMethod(shop, "RefreshUnlockStatus");
TryInvokeShopMethod(shop, "RefreshShownItems");
return true;
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: AddListingToShop", exception);
return false;
}
}
private static bool TryInvokeShopMethod(ShopInterface shop, string methodName, params object[] args)
{
try
{
if ((Object)(object)shop == (Object)null || string.IsNullOrEmpty(methodName))
{
return false;
}
BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
MethodInfo[] methods = ((object)shop).GetType().GetMethods(bindingAttr);
foreach (MethodInfo methodInfo in methods)
{
if (!(methodInfo == null) && string.Equals(methodInfo.Name, methodName, StringComparison.Ordinal))
{
ParameterInfo[] parameters = methodInfo.GetParameters();
if (((args != null) ? args.Length : 0) == parameters.Length)
{
methodInfo.Invoke(shop, args);
return true;
}
}
}
}
catch (Exception ex)
{
ModLogger.Debug("BackpackShopIntegration: " + methodName + " invoke failed: " + ex.Message);
}
return false;
}
private static int ParseTierFromItemId(string itemId)
{
if (string.IsNullOrEmpty(itemId) || !itemId.StartsWith("PackRat_Backpack_Tier_", StringComparison.Ordinal))
{
return -1;
}
string s = itemId.Substring("PackRat_Backpack_Tier_".Length);
int result;
return int.TryParse(s, out result) ? result : (-1);
}
private static void CreateListingUI(ShopInterface shop, ShopListing listing, Sprite iconSprite)
{
try
{
object obj = ReflectionUtils.TryGetFieldOrProperty(shop, "ListingUIPrefab");
object obj2 = ReflectionUtils.TryGetFieldOrProperty(shop, "ListingContainer");
if (obj == null || obj2 == null)
{
ModLogger.Warn("BackpackShopIntegration: Shop missing ListingUIPrefab or ListingContainer.");
return;
}
object obj3 = ((obj is Component) ? obj : null);
GameObject val = ((obj3 != null) ? ((Component)obj3).gameObject : null);
Transform val2 = (Transform)((obj2 is Transform) ? obj2 : null);
if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null)
{
return;
}
GameObject val3 = Object.Instantiate<GameObject>(val, val2);
ListingUI component = val3.GetComponent<ListingUI>();
if ((Object)(object)component == (Object)null)
{
Object.Destroy((Object)(object)val3);
return;
}
component.Initialize(listing);
if ((Object)(object)iconSprite != (Object)null && (Object)(object)component.Icon != (Object)null)
{
component.Icon.sprite = iconSprite;
}
BindListingUIEvents(shop, component);
AddToListingUICollection(shop, component);
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: CreateListingUI", exception);
}
}
private static void BindListingUIEvents(ShopInterface shop, ListingUI listingUI)
{
try
{
Type typeFromHandle = typeof(ShopInterface);
MethodInfo listingClicked = typeFromHandle.GetMethod("ListingClicked", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
MethodInfo dropdownClicked = typeFromHandle.GetMethod("DropdownClicked", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
MethodInfo entryHovered = typeFromHandle.GetMethod("EntryHovered", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
MethodInfo entryUnhovered = typeFromHandle.GetMethod("EntryUnhovered", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (listingClicked != null)
{
listingUI.onClicked = (Action)Delegate.Combine(listingUI.onClicked, (Action)delegate
{
listingClicked.Invoke(shop, new object[1] { listingUI });
});
}
if (dropdownClicked != null)
{
listingUI.onDropdownClicked = (Action)Delegate.Combine(listingUI.onDropdownClicked, (Action)delegate
{
dropdownClicked.Invoke(shop, new object[1] { listingUI });
});
}
if (entryHovered != null)
{
listingUI.hoverStart = (Action)Delegate.Combine(listingUI.hoverStart, (Action)delegate
{
entryHovered.Invoke(shop, new object[1] { listingUI });
});
}
if (entryUnhovered != null)
{
listingUI.hoverEnd = (Action)Delegate.Combine(listingUI.hoverEnd, (Action)delegate
{
entryUnhovered.Invoke(shop, null);
});
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: BindListingUIEvents", exception);
}
}
private static void AddToListingUICollection(ShopInterface shop, ListingUI listingUI)
{
try
{
FieldInfo field = typeof(ShopInterface).GetField("listingUI", BindingFlags.Instance | BindingFlags.NonPublic);
if (!(field == null))
{
object value = field.GetValue(shop);
value?.GetType().GetMethod("Add", new Type[1] { typeof(ListingUI) })?.Invoke(value, new object[1] { listingUI });
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: AddToListingUICollection", exception);
}
}
public static bool IsBackpackTierPurchase(string itemId, out int tierIndex)
{
tierIndex = ParseTierFromItemId(itemId ?? "");
return tierIndex >= 0;
}
public static void RemoveTierListingFromAllShops(int tierIndex)
{
if (tierIndex < 0 || tierIndex >= Configuration.BackpackTiers.Length)
{
return;
}
string itemId = "PackRat_Backpack_Tier_" + tierIndex;
List<int> list = new List<int>(_shopsIntegrated);
foreach (int item in list)
{
ShopInterface val = FindShopByInstanceId(item);
if ((Object)(object)val != (Object)null)
{
RemoveTierListingFromShop(val, itemId);
}
}
}
private static ShopInterface FindShopByInstanceId(int instanceId)
{
//IL_0079: Unknown result type (might be due to invalid IL or missing references)
//IL_0080: Expected O, but got Unknown
try
{
Type typeFromHandle = typeof(ShopInterface);
FieldInfo field = typeFromHandle.GetField("AllShops", BindingFlags.Static | BindingFlags.Public);
if (field != null && field.GetValue(null) is IEnumerable enumerable)
{
foreach (object item in enumerable)
{
if (item != null)
{
object obj = ((item is Object) ? item : null);
if (obj != null && ((Object)obj).GetInstanceID() == instanceId)
{
return (ShopInterface)item;
}
}
}
}
ShopInterface[] array = Utils.FindObjectsOfTypeSafe<ShopInterface>();
if (array != null)
{
for (int i = 0; i < array.Length; i++)
{
if ((Object)(object)array[i] != (Object)null && ((Object)array[i]).GetInstanceID() == instanceId)
{
return array[i];
}
}
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: FindShopByInstanceId", exception);
}
return null;
}
private static void RemoveTierListingFromShop(ShopInterface shop, string itemId)
{
if (shop?.Listings == null)
{
return;
}
try
{
object obj = null;
foreach (ShopListing listing in shop.Listings)
{
if ((Object)(object)listing?.Item != (Object)null && ((BaseItemDefinition)listing.Item).ID == itemId)
{
obj = listing;
break;
}
}
if (obj != null)
{
RemoveListingFromList(shop.Listings, obj);
RemoveAndDestroyListingUI(shop, obj);
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: RemoveTierListingFromShop", exception);
}
}
private static int GetListCount(object list)
{
if (list == null)
{
return 0;
}
object obj = ReflectionUtils.TryGetFieldOrProperty(list, "Count") ?? ReflectionUtils.TryGetFieldOrProperty(list, "count");
if (obj is int result)
{
return result;
}
if (obj is long num)
{
return (int)num;
}
return 0;
}
private static void RemoveListingFromList(object list, object listing)
{
if (list == null || listing == null)
{
return;
}
try
{
list.GetType().GetMethod("Remove", new Type[1] { listing.GetType() })?.Invoke(list, new object[1] { listing });
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: RemoveListingFromList", exception);
}
}
private static void RemoveAndDestroyListingUI(ShopInterface shop, object listing)
{
if ((Object)(object)shop == (Object)null || listing == null)
{
return;
}
try
{
object obj = typeof(ShopInterface).GetField("listingUI", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(shop);
if (obj == null)
{
return;
}
object obj2 = ReflectionUtils.TryGetFieldOrProperty(obj, "Count") ?? ReflectionUtils.TryGetFieldOrProperty(obj, "count");
int num2 = ((obj2 is int num) ? num : 0);
if (obj2 is long num3)
{
num2 = (int)num3;
}
for (int num4 = num2 - 1; num4 >= 0; num4--)
{
object obj3 = (obj.GetType().GetMethod("get_Item", new Type[1] { typeof(int) }) ?? obj.GetType().GetMethod("Get", new Type[1] { typeof(int) }))?.Invoke(obj, new object[1] { num4 });
if (obj3 != null)
{
object obj4 = ReflectionUtils.TryGetFieldOrProperty(obj3, "Listing") ?? ReflectionUtils.TryGetFieldOrProperty(obj3, "listing");
if (obj4 == listing)
{
object obj5 = ((obj3 is Component) ? obj3 : null);
GameObject val = ((obj5 != null) ? ((Component)obj5).gameObject : null);
if ((Object)(object)val != (Object)null)
{
Object.Destroy((Object)(object)val);
}
obj.GetType().GetMethod("RemoveAt", new Type[1] { typeof(int) })?.Invoke(obj, new object[1] { num4 });
break;
}
}
}
}
catch (Exception exception)
{
ModLogger.Error("BackpackShopIntegration: RemoveAndDestroyListingUI", exception);
}
}
}
}
namespace PackRat.Patches
{
[HarmonyPatch(typeof(ShopInterface))]
public static class BackpackPurchasePatch
{
[HarmonyPatch("ListingClicked", new Type[] { typeof(ListingUI) })]
[HarmonyPrefix]
public static bool ListingClicked_Prefix(ShopInterface __instance, ListingUI listingUI)
{
try
{
if ((Object)(object)listingUI == (Object)null)
{
return true;
}
object obj = ReflectionUtils.TryGetFieldOrProperty(listingUI, "Listing") ?? ReflectionUtils.TryGetFieldOrProperty(listingUI, "listing");
if (obj == null)
{
return true;
}
object obj2 = ReflectionUtils.TryGetFieldOrProperty(obj, "Item");
StorableItemDefinition val = (StorableItemDefinition)((obj2 is StorableItemDefinition) ? obj2 : null);
if (val == null || ((BaseItemDefinition)val).ID == null || !((BaseItemDefinition)val).ID.StartsWith("PackRat_Backpack_Tier_", StringComparison.Ordinal))
{
return true;
}
if (BackpackShopIntegration.IsBackpackTierPurchase(((BaseItemDefinition)val).ID, out var tierIndex) && (Object)(object)PlayerBackpack.Instance != (Object)null && tierIndex == PlayerBackpack.Instance.EquippedTierIndex)
{
ModLogger.Info($"Blocked purchase selection for currently equipped backpack tier {tierIndex}.");
return false;
}
return true;
}
catch (Exception exception)
{
ModLogger.Error("BackpackPurchasePatch: ListingClicked prefix error", exception);
return true;
}
}
}
[HarmonyPatch(typeof(BodySearchBehaviour))]
public static class BodySearchBehaviourPatch
{
[CompilerGenerated]
private sealed class <CheckForItems>d__1 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public BodySearchBehaviour behaviour;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <CheckForItems>d__1(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: Expected O, but got Unknown
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
((NPC)behaviour.officer).DialogueHandler.ShowWorldspaceDialogue("Hold on, let me see your backpack as well.", 5f);
<>2__current = (object)new WaitForSeconds(3f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
Singleton<BodySearchScreen>.Instance.IsOpen = false;
behaviour.ConcludeSearch(!PlayerBackpack.Instance.ContainsItemsOfInterest(behaviour.MaxStealthLevel));
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[HarmonyPatch("SearchClean")]
[HarmonyPrefix]
public static bool SearchClean(BodySearchBehaviour __instance)
{
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Expected O, but got Unknown
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Expected O, but got Unknown
if ((Object)(object)PlayerBackpack.Instance == (Object)null || !Configuration.Instance.EnableSearch || !PlayerBackpack.Instance.IsUnlocked || !PlayerBackpack.Instance.IsPoliceSearchable)
{
return true;
}
Singleton<BodySearchScreen>.Instance.onSearchClear.RemoveListener(new UnityAction(__instance.SearchClean));
Singleton<BodySearchScreen>.Instance.onSearchFail.RemoveListener(new UnityAction(__instance.SearchFail));
Singleton<BodySearchScreen>.Instance.IsOpen = true;
MelonCoroutines.Start(CheckForItems(__instance));
return false;
}
[IteratorStateMachine(typeof(<CheckForItems>d__1))]
private static IEnumerator CheckForItems(BodySearchBehaviour behaviour)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <CheckForItems>d__1(0)
{
behaviour = behaviour
};
}
}
[HarmonyPatch(typeof(Cart))]
public static class CartPatch
{
[HarmonyPatch("GetWarning")]
[HarmonyPostfix]
public static void GetWarning(Cart __instance, ref bool __result, ref string warning)
{
PlayerBackpack instance = PlayerBackpack.Instance;
if (!((Object)(object)instance == (Object)null) && instance.IsUnlocked && !warning.StartsWith("Vehicle") && __result)
{
List<ItemSlot> itemSlots = instance.ItemSlots;
itemSlots.InsertRange(0, (IEnumerable<ItemSlot>)PlayerSingleton<PlayerInventory>.Instance.hotbarSlots);
if (__instance.Shop.WillCartFit(itemSlots))
{
warning = "Inventory won't fit everything. Some items will be placed in your backpack.";
}
}
}
}
[HarmonyPatch(typeof(HandoverScreen))]
public static class HandoverScreenPatch
{
private sealed class PanelState
{
public RectTransform BackpackContainer;
public RectTransform BackpackSlotContainer;
public RectTransform BackpackHeaderRoot;
public RectTransform PagingRoot;
public RectTransform VehicleContainer;
public Component SourceTitleLabel;
public Component SourceSubtitleLabel;
public Component ClonedTitleLabel;
public Component ClonedSubtitleLabel;
public Component OverlayTitleLabel;
public Component OverlaySubtitleLabel;
public ItemSlotUI[] SlotUIs;
public Button PrevButton;
public Button NextButton;
public Button ToggleButton;
public Text PageLabel;
public Action PrevAction;
public Action NextAction;
public Action ToggleAction;
public Vector2 VehicleOriginalAnchoredPos;
public int CurrentPage;
public int SlotsPerPage;
public bool ShowingVehicle;
public int LastPageInputFrame;
public bool Initialized;
}
private sealed class HeaderCandidate
{
public Component Label;
public float LocalY;
public float FontSize;
}
[CompilerGenerated]
private sealed class <ReapplyHeaderNextFrame>d__9 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public HandoverScreen screen;
public PanelState panel;
private int <i>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <ReapplyHeaderNextFrame>d__9(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
if ((Object)(object)screen == (Object)null || panel == null)
{
return false;
}
<i>5__1 = 0;
break;
case 1:
<>1__state = -1;
if ((Object)(object)screen == (Object)null || panel == null || (Object)(object)panel.BackpackContainer == (Object)null || !((Component)panel.BackpackContainer).gameObject.activeSelf)
{
return false;
}
if (panel.ShowingVehicle)
{
return false;
}
if ((Object)(object)panel.VehicleContainer != (Object)null && ((Component)panel.VehicleContainer).gameObject.activeSelf)
{
((Component)panel.VehicleContainer).gameObject.SetActive(false);
}
ApplyPrimaryHeaderForMode(screen, panel, showingVehicle: false);
<i>5__1++;
break;
}
if (<i>5__1 < 3)
{
<>2__current = null;
<>1__state = 1;
return true;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private const float VehicleMaxDistance = 20f;
private const string VehicleHeaderTitle = "Vehicle";
private const string VehicleHeaderSubtitle = "This is the vehicle you last drove.\nMust be within 20 meters.";
private static readonly Dictionary<int, PanelState> States = new Dictionary<int, PanelState>();
private const int HeaderReapplyFrameCount = 3;
[HarmonyPatch("Start")]
[HarmonyPostfix]
public static void Start(HandoverScreen __instance)
{
try
{
PruneDeadStates();
EnsurePanel(__instance);
}
catch (Exception exception)
{
ModLogger.Error("HandoverScreenPatch.Start", exception);
}
}
[HarmonyPatch("Open")]
[HarmonyPostfix]
public static void Open(HandoverScreen __instance)
{
try
{
PruneDeadStates();
if (!HasBackpack())
{
HidePanelAndRestoreVehicle(__instance);
return;
}
PanelState panelState = EnsurePanel(__instance);
if (panelState != null && !((Object)(object)panelState.BackpackContainer == (Object)null))
{
panelState.CurrentPage = 0;
panelState.SlotsPerPage = ((panelState.SlotUIs != null) ? panelState.SlotUIs.Length : 0);
panelState.ShowingVehicle = false;
((Component)panelState.BackpackContainer).gameObject.SetActive(true);
if ((Object)(object)panelState.PagingRoot != (Object)null)
{
((Component)panelState.PagingRoot).gameObject.SetActive(true);
}
UpdateBackpackHeaderTexts(panelState);
bool flag = HasNearbyVehicleStorage();
if ((Object)(object)__instance.NoVehicle != (Object)null)
{
__instance.NoVehicle.SetActive(!flag && !((Component)panelState.BackpackContainer).gameObject.activeSelf);
}
ApplyVisibleStorageMode(panelState, flag);
if ((Object)(object)__instance.NoVehicle != (Object)null)
{
__instance.NoVehicle.SetActive(false);
}
if ((Object)(object)panelState.BackpackContainer != (Object)null)
{
((Component)panelState.BackpackContainer).gameObject.SetActive(true);
}
if ((Object)(object)panelState.BackpackSlotContainer != (Object)null)
{
((Component)panelState.BackpackSlotContainer).gameObject.SetActive(true);
}
if ((Object)(object)panelState.VehicleContainer != (Object)null)
{
((Component)panelState.VehicleContainer).gameObject.SetActive(false);
}
ApplyPrimaryHeaderForMode(__instance, panelState, panelState.ShowingVehicle);
MelonCoroutines.Start(ReapplyHeaderNextFrame(__instance, panelState));
ApplyBackpackPage(panelState);
RebuildQuickMove(__instance, flag);
}
}
catch (Exception exception)
{
ModLogger.Error("HandoverScreenPatch.Open", exception);
}
}
[IteratorStateMachine(typeof(<ReapplyHeaderNextFrame>d__9))]
private static IEnumerator ReapplyHeaderNextFrame(HandoverScreen screen, PanelState panel)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <ReapplyHeaderNextFrame>d__9(0)
{
screen = screen,
panel = panel
};
}
[HarmonyPatch("Update")]
[HarmonyPostfix]
public static void Update(HandoverScreen __instance)
{
PruneDeadStates();
if ((Object)(object)__instance == (Object)null || !States.TryGetValue(((Object)__instance).GetInstanceID(), out var value) || (Object)(object)value.BackpackContainer == (Object)null || !((Component)value.BackpackContainer).gameObject.activeSelf || value.ShowingVehicle)
{
return;
}
if ((Object)(object)value.VehicleContainer != (Object)null && ((Component)value.VehicleContainer).gameObject.activeSelf)
{
((Component)value.VehicleContainer).gameObject.SetActive(false);
}
ApplyPrimaryHeaderForMode(__instance, value, showingVehicle: false);
if ((Object)(object)value.BackpackHeaderRoot != (Object)null && ((Component)value.BackpackHeaderRoot).gameObject.activeSelf)
{
((Transform)value.BackpackHeaderRoot).SetAsLastSibling();
Canvas component = ((Component)value.BackpackHeaderRoot).GetComponent<Canvas>();
if ((Object)(object)component != (Object)null && component.overrideSorting && component.sortingOrder != 9999)
{
component.sortingOrder = 9999;
}
}
}
[HarmonyPatch("Close")]
[HarmonyPostfix]
public static void Close(HandoverScreen __instance)
{
//IL_009e: Unknown result type (might be due to invalid IL or missing references)
try
{
if (States.TryGetValue(((Object)__instance).GetInstanceID(), out var value))
{
ClearSlotAssignments(value);
if ((Object)(object)value.BackpackContainer != (Object)null)
{
((Component)value.BackpackContainer).gameObject.SetActive(false);
}
if ((Object)(object)value.PagingRoot != (Object)null)
{
((Component)value.PagingRoot).gameObject.SetActive(false);
}
HideOverlayHeader(value);
SetHeaderPairActive(value.SourceTitleLabel, value.SourceSubtitleLabel, active: true);
if ((Object)(object)value.VehicleContainer != (Object)null)
{
value.VehicleContainer.anchoredPosition = value.VehicleOriginalAnchoredPos;
}
}
}
catch (Exception exception)
{
ModLogger.Error("HandoverScreenPatch.Close", exception);
}
}
private static PanelState EnsurePanel(HandoverScreen screen)
{
//IL_0100: Unknown result type (might be due to invalid IL or missing references)
//IL_0105: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Unknown result type (might be due to invalid IL or missing references)
PruneDeadStates();
if ((Object)(object)screen == (Object)null)
{
return null;
}
int instanceID = ((Object)screen).GetInstanceID();
if (States.TryGetValue(instanceID, out var value) && value.Initialized && IsComponentAlive((Component)(object)value.BackpackContainer) && IsComponentAlive((Component)(object)value.VehicleContainer) && ((Object)(object)value.BackpackHeaderRoot == (Object)null || IsComponentAlive((Component)(object)value.BackpackHeaderRoot)) && IsComponentAlive((Component)(object)value.PagingRoot) && IsComponentAlive((Component)(object)value.PrevButton) && IsComponentAlive((Component)(object)value.NextButton) && IsComponentAlive((Component)(object)value.ToggleButton) && IsComponentAlive((Component)(object)value.PageLabel))
{
RefreshHeaderBindings(value, screen);
return value;
}
PanelState panelState = value ?? new PanelState();
panelState.VehicleContainer = screen.VehicleContainer;
if ((Object)(object)panelState.VehicleContainer == (Object)null)
{
return null;
}
panelState.VehicleOriginalAnchoredPos = panelState.VehicleContainer.anchoredPosition;
if (!IsComponentAlive((Component)(object)panelState.BackpackContainer))
{
panelState.BackpackContainer = null;
}
if ((Object)(object)panelState.BackpackContainer == (Object)null)
{
RectTransform val = Object.Instantiate<RectTransform>(panelState.VehicleContainer, ((Transform)panelState.VehicleContainer).parent);
((Object)val).name = "BackpackContainer";
val.anchoredPosition = panelState.VehicleOriginalAnchoredPos;
((Transform)val).localScale = ((Transform)panelState.VehicleContainer).localScale;
((Component)val).gameObject.SetActive(false);
panelState.BackpackContainer = val;
}
panelState.BackpackSlotContainer = FindMatchingRectTransform(panelState.BackpackContainer, screen.VehicleSlotContainer);
RectTransform val2 = (((Object)(object)panelState.BackpackSlotContainer != (Object)null) ? panelState.BackpackSlotContainer : panelState.BackpackContainer);
panelState.SlotUIs = ((Component)val2).GetComponentsInChildren<ItemSlotUI>(false);
if (panelState.SlotUIs == null || panelState.SlotUIs.Length == 0)
{
panelState.SlotUIs = ((Component)val2).GetComponentsInChildren<ItemSlotUI>(true);
}
RefreshHeaderBindings(panelState, screen);
EnsurePagingControls(panelState);
panelState.Initialized = true;
States[instanceID] = panelState;
return panelState;
}
private static void PruneDeadStates()
{
if (States.Count == 0)
{
return;
}
List<int> list = new List<int>();
foreach (KeyValuePair<int, PanelState> state in States)
{
PanelState value = state.Value;
if (value == null)
{
list.Add(state.Key);
}
else if (!IsComponentAlive((Component)(object)value.VehicleContainer) && !IsComponentAlive((Component)(object)value.BackpackContainer) && !IsComponentAlive((Component)(object)value.PagingRoot) && !IsComponentAlive((Component)(object)value.BackpackHeaderRoot))
{
list.Add(state.Key);
}
}
for (int i = 0; i < list.Count; i++)
{
States.Remove(list[i]);
}
}
private static void RefreshHeaderBindings(PanelState state, HandoverScreen screen)
{
if (state != null)
{
ResolveLabels(state, screen);
EnsureBackpackHeader(state);
}
}
private static void ResolveLabels(PanelState state, HandoverScreen screen)
{
ResolveHeaderPairInContainer(state.VehicleContainer, (Transform)(object)screen?.VehicleSlotContainer, null, null, out state.SourceTitleLabel, out state.SourceSubtitleLabel);
ResolveHeaderPairInContainer(state.BackpackContainer, (Transform)(object)state.BackpackSlotContainer, (Transform)(object)state.PagingRoot, (Transform)(object)state.BackpackHeaderRoot, out state.ClonedTitleLabel, out state.ClonedSubtitleLabel);
}
private static void ResolveHeaderPairInContainer(RectTransform container, Transform slotContainer, Transform pagingRoot, Transform overlayRoot, out Component titleLabel, out Component subtitleLabel)
{
titleLabel = null;
subtitleLabel = null;
if ((Object)(object)container == (Object)null)
{
return;
}
Component[] componentsInChildren = ((Component)container).GetComponentsInChildren<Component>(true);
List<Component> list = new List<Component>();
foreach (Component val in componentsInChildren)
{
if (!((Object)(object)val == (Object)null) && IsTextLikeComponent(val) && !IsUnderTransform(val, slotContainer) && !IsUnderTransform(val, pagingRoot) && !IsUnderTransform(val, overlayRoot))
{
list.Add(val);
}
}
if (list.Count == 0)
{
return;
}
titleLabel = FindNamedHeaderLabel(container, slotContainer, pagingRoot, overlayRoot, "Title");
subtitleLabel = FindNamedHeaderLabel(container, slotContainer, pagingRoot, overlayRoot, "Subtitle");
foreach (Component item in list)
{
string text = NormalizeLabelText(GetLabelText(item));
if ((Object)(object)titleLabel == (Object)null && text.Equals("Vehicle", StringComparison.OrdinalIgnoreCase))
{
titleLabel = item;
}
else if ((Object)(object)subtitleLabel == (Object)null && (text.Contains("vehicle you last drove", StringComparison.OrdinalIgnoreCase) || text.Contains("within 20 meters", StringComparison.OrdinalIgnoreCase)))
{
subtitleLabel = item;
}
}
if ((Object)(object)titleLabel != (Object)null && (Object)(object)subtitleLabel != (Object)null)
{
return;
}
List<HeaderCandidate> list2 = new List<HeaderCandidate>(list.Count);
for (int j = 0; j < list.Count; j++)
{
Component val2 = list[j];
list2.Add(new HeaderCandidate
{
Label = val2,
LocalY = GetLocalY(container, val2),
FontSize = GetFontSize(val2)
});
}
list2.Sort(CompareHeaderCandidates);
if ((Object)(object)titleLabel == (Object)null && list2.Count > 0)
{
titleLabel = list2[0].Label;
}
if (!((Object)(object)subtitleLabel == (Object)null))
{
return;
}
for (int k = 0; k < list2.Count; k++)
{
Component label = list2[k].Label;
if (!((Object)(object)label == (Object)null) && !((Object)(object)label == (Object)(object)titleLabel))
{
subtitleLabel = label;
break;
}
}
}
private static Component FindNamedHeaderLabel(RectTransform container, Transform slotContainer, Transform pagingRoot, Transform overlayRoot, string targetName)
{
if ((Object)(object)container == (Object)null || string.IsNullOrEmpty(targetName))
{
return null;
}
Transform[] componentsInChildren = ((Component)container).GetComponentsInChildren<Transform>(true);
foreach (Transform val in componentsInChildren)
{
if (!((Object)(object)val == (Object)null) && string.Equals(((Object)val).name, targetName, StringComparison.OrdinalIgnoreCase) && (!((Object)(object)slotContainer != (Object)null) || (!((Object)(object)val == (Object)(object)slotContainer) && !val.IsChildOf(slotContainer))) && (!((Object)(object)pagingRoot != (Object)null) || (!((Object)(object)val == (Object)(object)pagingRoot) && !val.IsChildOf(pagingRoot))) && (!((Object)(object)overlayRoot != (Object)null) || (!((Object)(object)val == (Object)(object)overlayRoot) && !val.IsChildOf(overlayRoot))))
{
Component textLikeComponent = GetTextLikeComponent(((Component)val).gameObject);
if ((Object)(object)textLikeComponent != (Object)null)
{
return textLikeComponent;
}
Component val2 = FindFirstTextLikeInSubtree(val);
if ((Object)(object)val2 != (Object)null)
{
return val2;
}
}
}
return null;
}
private static Component FindFirstTextLikeInSubtree(Transform root)
{
if ((Object)(object)root == (Object)null)
{
return null;
}
Component[] componentsInChildren = ((Component)root).GetComponentsInChildren<Component>(true);
foreach (Component val in componentsInChildren)
{
if ((Object)(object)val != (Object)null && IsTextLikeComponent(val))
{
return val;
}
}
return null;
}
private static int CompareHeaderCandidates(HeaderCandidate left, HeaderCandidate right)
{
if (left == right)
{
return 0;
}
if (left == null)
{
return 1;
}
if (right == null)
{
return -1;
}
int num = right.LocalY.CompareTo(left.LocalY);
if (num != 0)
{
return num;
}
return right.FontSize.CompareTo(left.FontSize);
}
private static float GetLocalY(RectTransform container, Component component)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: 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)container == (Object)null || (Object)(object)component == (Object)null || (Object)(object)component.transform == (Object)null)
{
return float.MinValue;
}
try
{
Vector3 val = ((Transform)container).InverseTransformPoint(component.transform.position);
return val.y;
}
catch
{
return float.MinValue;
}
}
private static float GetFontSize(Component label)
{
if ((Object)(object)label == (Object)null)
{
return 0f;
}
TextMeshProUGUI val = (TextMeshProUGUI)(object)((label is TextMeshProUGUI) ? label : null);
if (val != null)
{
try
{
return ((TMP_Text)val).fontSize;
}
catch
{
}
}
Text val2 = (Text)(object)((label is Text) ? label : null);
if (val2 != null)
{
return val2.fontSize;
}
object obj2 = ReflectionUtils.TryGetFieldOrProperty(label, "fontSize");
if (obj2 is float result)
{
return result;
}
if (obj2 is int num)
{
return num;
}
return 0f;
}
private static Component GetTextLikeComponent(GameObject gameObject)
{
if ((Object)(object)gameObject == (Object)null)
{
return null;
}
TextMeshProUGUI tmpLabel = GetTmpLabel(gameObject);
if ((Object)(object)tmpLabel != (Object)null)
{
return (Component)(object)tmpLabel;
}
Text component = gameObject.GetComponent<Text>();
if ((Object)(object)component != (Object)null)
{
return (Component)(object)component;
}
Component[] components = gameObject.GetComponents<Component>();
foreach (Component val in components)
{
if ((Object)(object)val != (Object)null && IsTextLikeComponent(val))
{
return val;
}
}
return null;
}
private static void EnsureBackpackHeader(PanelState state)
{
//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
//IL_00d4: Expected O, but got Unknown
if ((Object)(object)state?.BackpackContainer == (Object)null || (Object)(object)state.SourceTitleLabel == (Object)null || (Object)(object)state.SourceSubtitleLabel == (Object)null)
{
return;
}
RectTransform backpackContainer = state.BackpackContainer;
RectTransform val = null;
if ((Object)(object)state.BackpackHeaderRoot != (Object)null && IsComponentAlive((Component)(object)state.BackpackHeaderRoot))
{
val = state.BackpackHeaderRoot;
}
if ((Object)(object)val != (Object)null && (Object)(object)((Transform)val).parent != (Object)(object)backpackContainer)
{
((Transform)val).SetParent((Transform)(object)backpackContainer, false);
}
if ((Object)(object)val == (Object)null)
{
Transform val2 = ((Transform)backpackContainer).Find("PackRat_BackpackHeader");
val = (RectTransform)(object)((val2 is RectTransform) ? val2 : null);
}
if ((Object)(object)val == (Object)null)
{
GameObject val3 = new GameObject("PackRat_BackpackHeader");
val = val3.AddComponent<RectTransform>();
((Transform)val).SetParent((Transform)(object)backpackContainer, false);
}
state.BackpackHeaderRoot = val;
EnsureIgnoredByLayout(val);
ResetHeaderOverlayRoot(val);
state.OverlayTitleLabel = EnsureOverlayLabel(val, "PackRat_BackpackTitle", state.SourceTitleLabel);
state.OverlaySubtitleLabel = EnsureOverlayLabel(val, "PackRat_BackpackSubtitle", state.SourceSubtitleLabel);
UpdateBackpackHeaderLayout(state);
if (TryGetGameObject((Component)(object)val, out var gameObject) && TryGetGameObject((Component)(object)backpackContainer, out var gameObject2))
{
SetLayerRecursively(gameObject, gameObject2.layer);
((Transform)val).SetAsLastSibling();
Canvas componentInParent = ((Component)backpackContainer).GetComponentInParent<Canvas>();
Canvas val4 = gameObject.GetComponent<Canvas>();
if ((Object)(object)val4 == (Object)null)
{
val4 = gameObject.AddComponent<Canvas>();
}
val4.overrideSorting = true;
if ((Object)(object)componentInParent != (Object)null)
{
val4.sortingLayerID = componentInParent.sortingLayerID;
val4.sortingOrder = componentInParent.sortingOrder + 210;
}
else
{
val4.sortingOrder = 5010;
}
}
UpdateBackpackHeaderTexts(state);
}
private static void UpdateBackpackHeaderLayout(PanelState state)
{
//IL_0043: 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_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)state?.BackpackHeaderRoot == (Object)null) && !((Object)(object)state.BackpackContainer == (Object)null))
{
RectTransform backpackHeaderRoot = state.BackpackHeaderRoot;
EnsureIgnoredByLayout(backpackHeaderRoot);
backpackHeaderRoot.anchorMin = new Vector2(0.5f, 1f);
backpackHeaderRoot.anchorMax = new Vector2(0.5f, 1f);
backpackHeaderRoot.pivot = new Vector2(0.5f, 1f);
backpackHeaderRoot.anchoredPosition = new Vector2(0f, -8f);
((Transform)backpackHeaderRoot).localScale = Vector3.one;
}
}
private static void ResetHeaderOverlayRoot(RectTransform headerRoot)
{
//IL_001c: 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_0048: 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_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: 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)
if (!((Object)(object)headerRoot == (Object)null))
{
headerRoot.anchorMin = new Vector2(0.5f, 0.5f);
headerRoot.anchorMax = new Vector2(0.5f, 0.5f);
headerRoot.pivot = new Vector2(0.5f, 0.5f);
headerRoot.anchoredPosition3D = Vector3.zero;
((Transform)headerRoot).localRotation = Quaternion.identity;
((Transform)headerRoot).localScale = Vector3.one;
headerRoot.sizeDelta = Vector2.zero;
headerRoot.offsetMin = Vector2.zero;
headerRoot.offsetMax = Vector2.zero;
}
}
private static Component EnsureOverlayLabel(RectTransform parent, string name, Component sourceLabel)
{
if ((Object)(object)parent == (Object)null || (Object)(object)sourceLabel == (Object)null)
{
return null;
}
Transform val = ((Transform)parent).Find(name);
Component val2 = null;
if ((Object)(object)val != (Object)null)
{
val2 = GetTextLikeComponent(((Component)val).gameObject);
}
if ((Object)(object)val2 == (Object)null)
{
GameObject gameObject = sourceLabel.gameObject;
if ((Object)(object)gameObject == (Object)null)
{
return null;
}
GameObject val3 = Object.Instantiate<GameObject>(gameObject, (Transform)(object)parent);
((Object)val3).name = name;
val2 = GetTextLikeComponent(val3);
}
if ((Object)(object)val2 == (Object)null)
{
return null;
}
if (TryGetRectTransform(sourceLabel, out var rectTransform) && TryGetRectTransform(val2, out var rectTransform2))
{
CopyRectTransform(rectTransform, rectTransform2);
}
CopyLabelPresentation(sourceLabel, val2);
return val2;
}
private static void CopyRectTransform(RectTransform source, RectTransform target)
{
//IL_001c: 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_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0043: Unknown result type (might be due to invalid IL or missing references)
//IL_0050: 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_006a: 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_0084: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null))
{
target.anchorMin = source.anchorMin;
target.anchorMax = source.anchorMax;
target.pivot = source.pivot;
target.anchoredPosition3D = source.anchoredPosition3D;
target.sizeDelta = source.sizeDelta;
target.offsetMin = source.offsetMin;
target.offsetMax = source.offsetMax;
((Transform)target).localRotation = ((Transform)source).localRotation;
((Transform)target).localScale = ((Transform)source).localScale;
}
}
private static void CopyLabelPresentation(Component source, Component target)
{
//IL_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0067: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)source == (Object)null || (Object)(object)target == (Object)null)
{
return;
}
TextMeshProUGUI val = (TextMeshProUGUI)(object)((source is TextMeshProUGUI) ? source : null);
if (val != null)
{
TextMeshProUGUI val2 = (TextMeshProUGUI)(object)((target is TextMeshProUGUI) ? target : null);
if (val2 != null)
{
((TMP_Text)val2).font = ((TMP_Text)val).font;
((TMP_Text)val2).fontSize = ((TMP_Text)val).fontSize;
((TMP_Text)val2).fontStyle = ((TMP_Text)val).fontStyle;
((TMP_Text)val2).alignment = ((TMP_Text)val).alignment;
((Graphic)val2).color = ((Graphic)val).color;
((Graphic)val2).raycastTarget = false;
return;
}
}
Text val3 = (Text)(object)((source is Text) ? source : null);
if (val3 != null)
{
Text val4 = (Text)(object)((target is Text) ? target : null);
if (val4 != null)
{
val4.font = val3.font;
val4.fontSize = val3.fontSize;
val4.fontStyle = val3.fontStyle;
val4.alignment = val3.alignment;
((Graphic)val4).color = ((Graphic)val3).color;
((Graphic)val4).raycastTarget = false;
}
}
}
private static void EnsureIgnoredByLayout(RectTransform rectTransform)
{
if (!((Object)(object)rectTransform == (Object)null))
{
LayoutElement val = ((Component)rectTransform).GetComponent<LayoutElement>();
if ((Object)(object)val == (Object)null)
{
val = ((Component)rectTransform).gameObject.AddComponent<LayoutElement>();
}
if ((Object)(object)val != (Object)null)
{
val.ignoreLayout = true;
}
}
}
private static string GetBackpackDisplayName()
{
PlayerBackpack instance = PlayerBackpack.Instance;
string text = instance?.CurrentTier?.Name;
if (!string.IsNullOrEmpty(text))
{
return text;
}
int num = instance?.CurrentTierIndex ?? (-1);
if (num >= 0 && num < Configuration.BackpackTiers.Length)
{
return Configuration.BackpackTiers[num].Name;
}
return "Backpack";
}
private static void ReplaceVehicleTextInContainer(RectTransform container, string backpackTitle)
{
if ((Object)(object)container == (Object)null || string.IsNullOrEmpty(backpackTitle))
{
return;
}
Component[] componentsInChildren = ((Component)container).GetComponentsInChildren<Component>(true);
foreach (Component val in componentsInChildren)
{
if (!((Object)(object)val == (Object)null) && IsTextLikeComponent(val))
{
string text = NormalizeLabelText(GetLabelText(val));
if (text.Equals("Vehicle", StringComparison.OrdinalIgnoreCase))
{
SetLabelText(val, backpackTitle);
}
}
}
}
private static void ReplaceVehicleTextEverywhere(PanelState panel, string backpackTitle)
{
if (panel != null && !string.IsNullOrEmpty(backpackTitle) && (Object)(object)panel.BackpackContainer != (Object)null)
{
ReplaceVehicleTextInContainer(panel.BackpackContainer, backpackTitle);
}
}
private static void UpdateBackpackHeaderTexts(PanelState state)
{
if (state != null)
{
if ((Object)(object)state.OverlayTitleLabel != (Object)null)
{
SetLabelText(state.OverlayTitleLabel, GetBackpackDisplayName());
}
if ((Object)(object)state.OverlaySubtitleLabel != (Object)null)
{
SetLabelText(state.OverlaySubtitleLabel, "Items from your backpack.");
}
}
}
private static void EnsurePagingControls(PanelState state)
{
//IL_0247: Unknown result type (might be due to invalid IL or missing references)
//IL_0283: 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_00d4: Expected O, but got Unknown
//IL_0104: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Unknown result type (might be due to invalid IL or missing references)
//IL_0128: Unknown result type (might be due to invalid IL or missing references)
//IL_015b: Unknown result type (might be due to invalid IL or missing references)
//IL_0160: Unknown result type (might be due to invalid IL or missing references)
//IL_02bf: 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_0398: 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_036f: Unknown result type (might be due to invalid IL or missing references)
//IL_03f6: Unknown result type (might be due to invalid IL or missing references)
//IL_0416: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)state.BackpackContainer == (Object)null)
{
return;
}
Transform val = ((Transform)state.BackpackContainer).Find("PackRat_Paging");
if ((Object)(object)val == (Object)null)
{
Transform parent = ((Transform)state.BackpackContainer).parent;
if ((Object)(object)parent != (Object)null)
{
val = parent.Find("PackRat_Paging");
}
}
if ((Object)(object)val != (Object)null && (Object)(object)val.parent != (Object)(object)state.BackpackContainer)
{
val.SetParent((Transform)(object)state.BackpackContainer, false);
}
if ((Object)(object)val == (Object)null)
{
GameObject val2 = new GameObject("PackRat_Paging");
val = val2.transform;
val.SetParent((Transform)(object)state.BackpackContainer, false);
RectTransform val3 = val2.AddComponent<RectTransform>();
val3.pivot = new Vector2(0.5f, 1f);
val3.sizeDelta = new Vector2(176f, 58f);
((Transform)val3).localScale = Vector3.one;
LayoutElement val4 = val2.AddComponent<LayoutElement>();
val4.ignoreLayout = true;
Image val5 = val2.AddComponent<Image>();
((Graphic)val5).color = Color32.op_Implicit(new Color32((byte)16, (byte)16, (byte)16, (byte)185));
((Graphic)val5).raycastTarget = false;
}
EnsurePagingBackground(val);
LayoutElement val6 = null;
try
{
val6 = ((Component)val).GetComponent<LayoutElement>();
}
catch
{
}
if ((Object)(object)val6 == (Object)null)
{
try
{
val6 = ((Component)val).gameObject.AddComponent<LayoutElement>();
}
catch
{
}
}
if ((Object)(object)val6 != (Object)null)
{
val6.ignoreLayout = true;
}
state.PrevButton = FindPagerButton(val, "PackRat_PrevButton");
state.NextButton = FindPagerButton(val, "PackRat_NextButton");
state.ToggleButton = FindPagerButton(val, "PackRat_ViewToggleButton");
state.PageLabel = FindPagerLabel(val);
if ((Object)(object)state.PrevButton == (Object)null)
{
state.PrevButton = CreatePagerButton("<", val, new Vector2(-70f, -1f));
}
if ((Object)(object)state.NextButton == (Object)null)
{
state.NextButton = CreatePagerButton(">", val, new Vector2(70f, -1f));
}
if ((Object)(object)state.ToggleButton == (Object)null)
{
state.ToggleButton = CreateToggleButton("Show Vehicle", val, new Vector2(0f, -30f));
}
if ((Object)(object)state.PageLabel == (Object)null)
{
state.PageLabel = CreatePagerLabel(val, new Vector2(0f, -1f));
}
if ((Object)(object)state.PageLabel != (Object)null && ((Object)state.PageLabel).name != "PackRat_PageLabel")
{
state.PageLabel = null;
}
if ((Object)(object)state.PageLabel == (Object)null)
{
state.PageLabel = CreatePagerLabel(val, new Vector2(0f, -1f));
}
ConfigurePagerButton(state.PrevButton, "<", new Vector2(-70f, -10f));
ConfigurePagerButton(state.NextButton, ">", new Vector2(70f, -10f));
ConfigureToggleButton(state.ToggleButton, state.ShowingVehicle ? "Show Backpack" : "Show Vehicle", new Vector2(0f, -34f));
ConfigurePagerLabel(state.PageLabel, new Vector2(0f, -10f));
RectTransform val7 = null;
try
{
val7 = ((Component)val).GetComponent<RectTransform>();
}
catch
{
}
if ((Object)(object)val7 == (Object)null)
{
try
{
val7 = ((Component)val).gameObject.AddComponent<RectTransform>();
}
catch
{
}
}
state.PagingRoot = val7;
UpdatePagingLayout(state);
if (TryGetGameObject((Component)(object)val, out var gameObject) && TryGetGameObject((Component)(object)state.BackpackContainer, out var gameObject2))
{
SetLayerRecursively(gameObject, gameObject2.layer);
val.SetAsLastSibling();
Canvas val8 = null;
try
{
val8 = ((Component)state.BackpackContainer).GetComponentInParent<Canvas>();
}
catch
{
}
Canvas val9 = null;
try
{
val9 = gameObject.GetComponent<Canvas>();
}
catch
{
}
if ((Object)(object)val9 == (Object)null)
{
try
{
val9 = gameObject.AddComponent<Canvas>();
}
catch
{
}
}
if ((Object)(object)val9 == (Object)null)
{
return;
}
val9.overrideSorting = true;
if ((Object)(object)val8 != (Object)null)
{
val9.sortingLayerID = val8.sortingLayerID;
val9.sortingOrder = val8.sortingOrder + 200;
}
else
{
val9.sortingOrder = 5000;
}
GraphicRaycaster val10 = null;
try
{
val10 = gameObject.GetComponent<GraphicRaycaster>();
}
catch
{
}
if ((Object)(object)val10 == (Object)null)
{
try
{
gameObject.AddComponent<GraphicRaycaster>();
}
catch
{
}
}
}
if (state.PrevAction == null)
{
state.PrevAction = delegate
{
if (state.LastPageInputFrame != Time.frameCount && state.CurrentPage > 0)
{
state.LastPageInputFrame = Time.frameCount;
state.CurrentPage--;
ApplyBackpackPage(state);
}
};
}
if (state.NextAction == null)
{
state.NextAction = delegate
{
if (state.LastPageInputFrame != Time.frameCount)
{
int totalPages = GetTotalPages(state);
if (state.CurrentPage < totalPages - 1)
{
state.LastPageInputFrame = Time.frameCount;
state.CurrentPage++;
ApplyBackpackPage(state);
}
}
};
}
if (state.ToggleAction == null)
{
state.ToggleAction = delegate
{
bool flag = HasNearbyVehicleStorage();
if (!flag)
{
state.ShowingVehicle = false;
}
else
{
state.ShowingVehicle = !state.ShowingVehicle;
}
ApplyVisibleStorageMode(state, flag);
HandoverScreen screen = FindOwningScreen(state);
ApplyPrimaryHeaderForMode(screen, state, state.ShowingVehicle);
if (!state.ShowingVehicle)
{
MelonCoroutines.Start(ReapplyHeaderNextFrame(screen, state));
}
if (!state.ShowingVehicle)
{
ApplyBackpackPage(state);
}
else
{
UpdatePagerControls(state, GetTotalPages(state), flag);
}
};
}
if ((Object)(object)state.PrevButton != (Object)null)
{
EventHelper.RemoveListener(state.PrevAction, (UnityEvent)(object)state.PrevButton.onClick);
EventHelper.AddListener(state.PrevAction, (UnityEvent)(object)state.PrevButton.onClick);
}
if ((Object)(object)state.NextButton != (Object)null)
{
EventHelper.RemoveListener(state.NextAction, (UnityEvent)(object)state.NextButton.onClick);
EventHelper.AddListener(state.NextAction, (UnityEvent)(object)state.NextButton.onClick);
}
if ((Object)(object)state.ToggleButton != (Object)null)
{
EventHelper.RemoveListener(state.ToggleAction, (UnityEvent)(object)state.ToggleButton.onClick);
EventHelper.AddListener(state.ToggleAction, (UnityEvent)(object)state.ToggleButton.onClick);
}
}
private static Button CreatePagerButton(string text, Transform parent, Vector2 anchoredPos)
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected O, but got Unknown
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: 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_0087: Unknown result type (might be due to invalid IL or missing references)
//IL_0099: 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_00bc: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Expected O, but got Unknown
//IL_0101: 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_011b: 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_015a: Unknown result type (might be due to invalid IL or missing references)
GameObject val = new GameObject("PackRat_" + ((text == "<") ? "Prev" : "Next") + "Button");
val.transform.SetParent(parent, false);
RectTransform val2 = val.AddComponent<RectTransform>();
val2.anchorMin = new Vector2(0.5f, 0.5f);
val2.anchorMax = new Vector2(0.5f, 0.5f);
val2.pivot = new Vector2(0.5f, 0.5f);
val2.anchoredPosition = anchoredPos;
val2.sizeDelta = new Vector2(24f, 24f);
Image val3 = val.AddComponent<Image>();
((Graphic)val3).color = Color32.op_Implicit(new Color32((byte)60, (byte)60, (byte)60, (byte)210));
Button val4 = val.AddComponent<Button>();
((Selectable)val4).targetGraphic = (Graphic)(object)val3;
GameObject val5 = new GameObject("Label");
val5.transf