Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MerchantStacker v1.0.1
MerchantStacker.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using HutongGames.PlayMaker; using HutongGames.PlayMaker.Actions; using InControl; using MerchantStacker.Patches; using Microsoft.CodeAnalysis; using TMProOld; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("MerchantStacker")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+8f0fc1654bce926d1feb93021b9281f4d06d4a57")] [assembly: AssemblyProduct("MerchantStacker")] [assembly: AssemblyTitle("MerchantStacker")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/RaincloudTheDragon/MerchantStacker")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Embedded] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] [Embedded] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace Microsoft.CodeAnalysis { [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace MerchantStacker { internal static class Eligibility { public static bool IsStackableShopOffer(ShopItem? item) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null) { return false; } if (item.IsAvailableNotInfinite) { return false; } if (!IsBulkTypeFlags(item.GetTypeFlags())) { return false; } if (item.Cost <= 0) { return false; } return item.Item is CollectableItem; } private static bool IsBulkTypeFlags(TypeFlags flags) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Invalid comparison between Unknown and I4 if ((int)flags != 0) { return (int)flags == 1; } return true; } public static bool StockHasStackableOffers(ShopMenuStock? stock) { if ((Object)(object)stock == (Object)null) { return false; } try { foreach (ShopItem item in ((ShopMenuStock)(((Object)(object)stock.MasterList != (Object)null) ? ((object)stock.MasterList) : ((object)stock))).EnumerateStock()) { if (IsStackableShopOffer(item)) { return true; } } int itemCount = stock.GetItemCount(); for (int i = 0; i < itemCount; i++) { GameObject itemGameObject = stock.GetItemGameObject(i); ShopItemStats obj = ((itemGameObject != null) ? itemGameObject.GetComponent<ShopItemStats>() : null); if (IsStackableShopOffer((obj != null) ? obj.Item : null)) { return true; } } } catch { } return false; } public static bool IsBulkEligible(ShopItem? item) { if ((Object)(object)item == (Object)null || !item.IsAvailable) { return false; } if (!IsStackableShopOffer(item)) { return false; } SavedItem item2 = item.Item; CollectableItem val = (CollectableItem)(object)((item2 is CollectableItem) ? item2 : null); if (val == null) { return false; } if (((SavedItem)val).CanGetMore()) { return !val.IsAtMax(); } return false; } public static bool ShouldOfferBulkQty(ShopItem? item) { if (!IsBulkEligible(item) || (Object)(object)item == (Object)null) { return false; } return GetMaxQuantity(item) >= 2; } public static int GetMaxQuantity(ShopItem item) { SavedItem item2 = item.Item; CollectableItem val = (CollectableItem)(object)((item2 is CollectableItem) ? item2 : null); if (val == null) { return 0; } int roomUntilCap = GetRoomUntilCap(val); int affordableCount = GetAffordableCount(item); return Math.Max(0, Math.Min(roomUntilCap, affordableCount)); } public static int GetRoomUntilCap(CollectableItem item) { if (!((SavedItem)item).CanGetMore() || item.IsAtMax()) { return 0; } int collectedAmount = item.CollectedAmount; int num = TryGetCap(item); if (num > 0) { return Math.Max(0, num - collectedAmount); } return 99; } public static int GetAffordableCount(ShopItem item) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 int cost = item.Cost; if (cost <= 0) { return 0; } CurrencyType currencyType = item.CurrencyType; if ((int)currencyType != 0) { if ((int)currencyType == 1) { return PlayerData.instance.ShellShards / cost; } return 0; } return PlayerData.instance.geo / cost; } public static int GetAffordableCount(int unitCost, CurrencyType currency) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 if (unitCost <= 0) { return 0; } if ((int)currency != 0) { if ((int)currency == 1) { return PlayerData.instance.ShellShards / unitCost; } return 0; } return PlayerData.instance.geo / unitCost; } private static int TryGetCap(CollectableItem item) { try { FieldInfo field = typeof(CollectableItem).GetField("customMaxAmount", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { int num = (int)field.GetValue(item); if (num > 0) { return num; } } } catch { } return 20; } } [BepInPlugin("io.github.raincloudthedragon.merchantstacker", "MerchantStacker", "1.0.0")] public class MerchantStackerPlugin : BaseUnityPlugin { public const string PluginGuid = "io.github.raincloudthedragon.merchantstacker"; public const string PluginName = "MerchantStacker"; public const string PluginVersion = "1.0.0"; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<int> DpadStep; internal static ConfigEntry<int> StickStep; internal static ConfigEntry<float> HoldInitialDelay; internal static ConfigEntry<float> HoldMinRepeat; internal static ConfigEntry<float> HoldAccel; private Harmony? _harmony; private GameObject? _pickerGo; internal static MerchantStackerPlugin Instance { get; private set; } internal static ManualLogSource Log { get; private set; } private void Awake() { //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Expected O, but got Unknown //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Enabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Enable bulk-buy quantity submenu."); DpadStep = ((BaseUnityPlugin)this).Config.Bind<int>("Controls", "DpadStep", 1, "Quantity change for d-pad up/down."); StickStep = ((BaseUnityPlugin)this).Config.Bind<int>("Controls", "StickStep", 5, "Quantity change for right stick up/down."); HoldInitialDelay = ((BaseUnityPlugin)this).Config.Bind<float>("Controls", "HoldInitialDelay", 0.35f, "Seconds before hold-repeat starts."); HoldMinRepeat = ((BaseUnityPlugin)this).Config.Bind<float>("Controls", "HoldMinRepeat", 0.05f, "Fastest hold-repeat interval in seconds."); HoldAccel = ((BaseUnityPlugin)this).Config.Bind<float>("Controls", "HoldAccel", 0.85f, "Multiply repeat interval by this each step while held (< 1 accelerates)."); _pickerGo = new GameObject("MerchantStacker_QuantityPicker"); Object.DontDestroyOnLoad((Object)(object)_pickerGo); ((Object)_pickerGo).hideFlags = (HideFlags)61; _pickerGo.AddComponent<QuantityPicker>(); _harmony = new Harmony("io.github.raincloudthedragon.merchantstacker"); TryPatch(typeof(ShopSelectionCachePatches)); TryPatch(typeof(ShopConfirmShowPatches)); TryPatch(typeof(ShopConfirmListPatches)); TryPatch(typeof(ConfirmDialogPatches)); TryPatch(typeof(InventoryPaneInputPatches)); TryPatch(typeof(ShopPurchasePatches)); TryPatch(typeof(SimpleShopPatches)); TryPatch(typeof(MachinePurchasePatches)); Log.LogInfo((object)"MerchantStacker v1.0.0 loaded (F6 ScriptEngine reload supported)."); } private void TryPatch(Type type) { try { _harmony.PatchAll(type); Log.LogInfo((object)("Patched " + type.Name)); } catch (Exception arg) { Log.LogError((object)$"Failed to patch {type.Name}: {arg}"); } } private void OnDestroy() { try { QuantityPicker.Instance?.ShutdownForReload(); } catch (Exception ex) { ManualLogSource log = Log; if (log != null) { log.LogWarning((object)("QuantityPicker unload: " + ex.Message)); } } if ((Object)(object)_pickerGo != (Object)null) { Object.DestroyImmediate((Object)(object)_pickerGo); _pickerGo = null; } PurchaseBatcher.ClearPendingQuantity(); PurchaseBatcher.ExpectingFsmPurchase = false; PurchaseBatcher.ClearShopPurchaseSuppression(); try { InventoryPaneInput.IsInputBlocked = false; } catch { } Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } _harmony = null; if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } ManualLogSource log2 = Log; if (log2 != null) { log2.LogInfo((object)"MerchantStacker unloaded."); } } } internal static class PurchaseBatcher { internal static int PendingQuantity { get; set; } internal static bool IsBatching { get; private set; } internal static bool BlockShopPurchases { get; private set; } internal static bool ExpectingFsmPurchase { get; set; } internal static void ClearPendingQuantity() { PendingQuantity = 0; } internal static int ConsumePendingQuantity() { int pendingQuantity = PendingQuantity; PendingQuantity = 0; return pendingQuantity; } internal static void BeginShopPurchaseBlock() { BlockShopPurchases = true; } internal static void EndShopPurchaseBlock() { BlockShopPurchases = false; } internal static void ClearShopPurchaseSuppression() { BlockShopPurchases = false; } internal static void BuyShopItem(ShopItemStats stats, int quantity, int subItemIndex, Action? onComplete) { if ((Object)(object)stats == (Object)null || (Object)(object)stats.Item == (Object)null) { onComplete?.Invoke(); return; } IsBatching = true; try { int num = 0; for (int i = 0; i < quantity; i++) { if (!stats.CanBuy()) { break; } if (stats.IsAtMax()) { break; } if (!stats.Item.IsAvailable) { break; } stats.SetPurchased((Action)null, subItemIndex); num++; } MerchantStackerPlugin.Log.LogInfo((object)$"Bought {num}x {stats.Item.DisplayName}"); if (num > 0) { BeginShopPurchaseBlock(); } } finally { IsBatching = false; } onComplete?.Invoke(); } internal static void BuyShopItem(ShopItem item, int quantity, int subItemIndex, Action? onComplete) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Invalid comparison between Unknown and I4 if ((Object)(object)item == (Object)null) { onComplete?.Invoke(); return; } IsBatching = true; try { int num = 0; for (int i = 0; i < quantity; i++) { if (!item.IsAvailable) { break; } if (item.IsAtMax()) { break; } CurrencyType currencyType = item.CurrencyType; if (!(((int)currencyType == 0) ? (PlayerData.instance.geo >= item.Cost) : ((int)currencyType == 1 && PlayerData.instance.ShellShards >= item.Cost))) { break; } item.SetPurchased((Action)null, subItemIndex); num++; } MerchantStackerPlugin.Log.LogInfo((object)$"Bought {num}x {item.DisplayName}"); if (num > 0) { BeginShopPurchaseBlock(); } } finally { IsBatching = false; } onComplete?.Invoke(); } } internal sealed class QuantityPicker : MonoBehaviour { private static readonly FieldInfo InstanceField = AccessTools.Field(typeof(DialogueYesNoBox), "_instance"); private static readonly FieldInfo CurrentYesField = AccessTools.Field(typeof(YesNoBox), "currentYes"); private static readonly FieldInfo CurrentNoField = AccessTools.Field(typeof(YesNoBox), "currentNo"); private static readonly FieldInfo SelectedStateField = AccessTools.Field(typeof(YesNoBox), "selectedState"); private static readonly MethodInfo DoEndMethod = AccessTools.Method(typeof(YesNoBox), "DoEnd", (Type[])null, (Type[])null); private static readonly FieldInfo RequiredCurrencyAmountField = AccessTools.Field(typeof(DialogueYesNoBox), "requiredCurrencyAmount"); private static readonly FieldInfo CurrencyTextField = AccessTools.Field(typeof(DialogueYesNoBox), "currencyText"); private static readonly FieldInfo InstantiatedItemsField = AccessTools.Field(typeof(DialogueYesNoBox), "instantiatedItems"); private static readonly FieldInfo WillGetItemField = AccessTools.Field(typeof(DialogueYesNoBox), "willGetItem"); private static readonly FieldInfo ItemTemplateField = AccessTools.Field(typeof(DialogueYesNoBox), "itemTemplate"); private static readonly FieldInfo ItemsLayoutField = AccessTools.Field(typeof(DialogueYesNoBox), "itemsLayout"); private static readonly FieldInfo ItemCostTextField = AccessTools.Field(typeof(ShopItemStats), "itemCostText"); private static readonly FieldInfo TitleTextField = AccessTools.Field(typeof(ShopMenuStock), "titleText"); private static readonly FieldInfo CostSpriteField = AccessTools.Field(typeof(ShopItemStats), "costSprite"); private static readonly FieldInfo ItemSpriteField = AccessTools.Field(typeof(ShopItemStats), "itemSprite"); private static readonly FieldInfo ScrollUpArrowField = AccessTools.Field(typeof(ScrollView), "upArrow"); private static readonly FieldInfo ScrollDownArrowField = AccessTools.Field(typeof(ScrollView), "downArrow"); private static Mesh? _cachedCaretMesh; private static Material? _cachedCaretMaterial; private static int _cachedCaretSortLayer; private static int _cachedCaretSortOrder; private static Sprite? _cachedArrowSprite; private static bool _arrowAssetsSearched; private bool _active; private bool _hijacked; private bool _inShop; private int _quantity = 1; private int _min = 1; private int _max = 1; private int _unitCost; private CurrencyType _currency; private string _title = "Buy"; private CollectableItem? _item; private ShopItemStats? _shopStats; private Transform? _shopRoot; private string? _originalCostText; private TextMeshPro? _boundCostText; private ShopMenuStock? _boundStock; private string? _originalShopTitle; private GameObject? _hudRoot; private TextMeshPro? _hudQty; private TextMeshPro? _hudCost; private GameObject? _hudArrowUp; private GameObject? _hudArrowDown; private SpriteRenderer? _hudCurrencyIcon; private GameObject? _hiddenConfirmList; private GameObject? _hiddenConfirmMsg; private readonly List<GameObject> _hiddenNativeCost = new List<GameObject>(); private readonly List<GameObject> _chromeToKeepOff = new List<GameObject>(); private GameObject? _itemArtSprite; private GameObject? _itemArtName; private SpriteRenderer? _itemArtSpriteSr; private TextMeshPro? _itemArtNameTmp; private int _lastHudQty = int.MinValue; private int _lastHudTotal = int.MinValue; private bool _lastArrowUpOn; private bool _lastArrowDownOn; private float _maxRecalcTimer; private int _chromeKeepOffFrame; private MeshRenderer? _itemArtNameMr; private Vector3 _qtyLocal; private Vector3 _costLocal; private Vector3 _currencyLocal; private Vector3 _arrowUpLocal; private Vector3 _arrowDownLocal; private Vector3 _arrowUpBaseLocalScale = Vector3.one; private Vector3 _arrowDownBaseLocalScale = Vector3.one; private Quaternion _arrowUpLocalRot = Quaternion.identity; private Quaternion _arrowDownLocalRot = Quaternion.identity; private Action? _originalYes; private Action? _originalNo; private Action<int>? _onConfirm; private Action? _onCancel; private Action? _purchaseDone; private Action? _shopCancel; private float _upTimer; private float _downTimer; private float _upInterval; private float _downInterval; private bool _upHeld; private bool _downHeld; private int _heldStep; internal static QuantityPicker? Instance { get; private set; } internal static bool SuppressHijack { get; private set; } public bool IsOpen => _active; public int CurrentQuantity => _quantity; private void Awake() { Instance = this; } internal void ShutdownForReload() { SuppressHijack = false; try { if (_active) { if (_inShop) { AbortInShopSession(resetShopWindow: true); } else { Finish(confirmed: false); } } else { DestroyInShopHud(restoreTexts: true); } } catch (Exception ex) { MerchantStackerPlugin.Log.LogWarning((object)("QuantityPicker shutdown: " + ex.Message)); } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } public void OpenInShop(Transform shopRoot, string title, CollectableItem? item, int unitCost, CurrencyType currency, int maxQuantity, ShopItemStats stats) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) if (MerchantStackerPlugin.Enabled.Value && maxQuantity >= 1 && !_active && !((Object)(object)((stats != null) ? stats.Item : null) == (Object)null)) { BeginSession(title, item, unitCost, currency, maxQuantity, hijacked: false); _inShop = true; _shopRoot = shopRoot; _shopStats = stats; _onConfirm = null; _onCancel = null; BindShopCostText(stats); BuildConfirmQtyHud(); if ((Object)(object)_hudRoot == (Object)null) { MerchantStackerPlugin.Log.LogWarning((object)"OpenInShop: HUD failed — restoring vanilla confirm"); _active = false; _inShop = false; _shopRoot = null; _shopStats = null; InventoryPaneInput.IsInputBlocked = false; ShopConfirmListPatches.RestoreConfirmChromePublic(); } else { RefreshInShopHud(); ((MonoBehaviour)this).StartCoroutine(EnsureHudSoon()); MerchantStackerPlugin.Log.LogInfo((object)$"In-shop qty: {_title} max={_max} cost={_unitCost} hud=True"); } } } public void ArmShopPurchaseSession(Action? onPurchaseComplete, Action? onCancelPurchase) { _purchaseDone = onPurchaseComplete; _shopCancel = onCancelPurchase; } private void LateUpdate() { if (_active && _inShop) { if ((++_chromeKeepOffFrame & 0xF) == 0) { KeepCachedItemArtVisible(); } Transform val = (Transform)(((Object)(object)_shopRoot != (Object)null) ? ((object)_shopRoot) : ((object)(((Object)(object)_shopStats != (Object)null) ? ((Component)_shopStats).transform.root : null))); if ((Object)(object)val == (Object)null || !Object.op_Implicit((Object)(object)val) || !((Component)val).gameObject.activeInHierarchy) { AbortInShopSession(resetShopWindow: true); } } } private void KeepCachedChromeOff() { for (int i = 0; i < _chromeToKeepOff.Count; i++) { GameObject val = _chromeToKeepOff[i]; if ((Object)(object)val != (Object)null && val.activeSelf) { val.SetActive(false); } } } private void KeepCachedItemArtVisible() { if ((Object)(object)_itemArtSprite != (Object)null && !_itemArtSprite.activeSelf) { _itemArtSprite.SetActive(true); } if ((Object)(object)_itemArtSpriteSr != (Object)null && !((Renderer)_itemArtSpriteSr).enabled) { ((Renderer)_itemArtSpriteSr).enabled = true; } if ((Object)(object)_itemArtName != (Object)null && !_itemArtName.activeSelf) { _itemArtName.SetActive(true); } if ((Object)(object)_itemArtNameTmp != (Object)null) { if (!((Behaviour)_itemArtNameTmp).enabled) { ((Behaviour)_itemArtNameTmp).enabled = true; } if ((Object)(object)_itemArtNameMr != (Object)null && !((Renderer)_itemArtNameMr).enabled) { ((Renderer)_itemArtNameMr).enabled = true; } } } private void CacheChromeToKeepOff(Transform confirm, Transform? confirmGroup) { _chromeToKeepOff.Clear(); Transform[] componentsInChildren = ((Component)(((Object)(object)confirmGroup != (Object)null) ? ((object)confirmGroup) : ((object)confirm))).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } string name = ((Object)val).name; if (!(name == "UI List") || !((Object)(object)val.parent != (Object)null) || !(((Object)val.parent).name == "Confirm")) { switch (name) { case "Yes": case "No": if (!ShopConfirmListPatches.IsUnderShopConfirmPublic(val)) { continue; } break; case "Confirm msg": case "Costs": case "Thankyou": case "Money": case "Item cost": case "Geo Sprite": break; default: continue; } } _chromeToKeepOff.Add(((Component)val).gameObject); } ShopConfirmShowPatches.LockConfirmChrome = true; KeepCachedChromeOff(); } private void CacheItemArt(Transform layoutParent) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown _itemArtSprite = null; _itemArtName = null; _itemArtSpriteSr = null; _itemArtNameTmp = null; foreach (Transform item in layoutParent) { Transform val = item; if (!((Object)(object)val == (Object)null)) { if (((Object)val).name == "Item Sprite") { _itemArtSprite = ((Component)val).gameObject; _itemArtSpriteSr = ((Component)val).GetComponent<SpriteRenderer>(); } else if (((Object)val).name == "Item name") { _itemArtName = ((Component)val).gameObject; _itemArtNameTmp = ((Component)val).GetComponent<TextMeshPro>(); _itemArtNameMr = (((Object)(object)_itemArtNameTmp != (Object)null) ? ((Component)_itemArtNameTmp).GetComponent<MeshRenderer>() : null); } } } } private Transform? GetShopMenuRoot() { try { if ((Object)(object)_shopStats != (Object)null) { return ((Component)_shopStats).transform.root; } if ((Object)(object)_shopRoot != (Object)null) { return _shopRoot.root; } } catch { } return null; } private void EnsureConfirmItemArtVisible() { Transform shopMenuRoot = GetShopMenuRoot(); if ((Object)(object)shopMenuRoot == (Object)null) { return; } Transform val = FindNamedTransform(shopMenuRoot, "Item Confirm Group"); if (!((Object)(object)val == (Object)null)) { if (!((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(true); } CacheItemArt(val); KeepCachedItemArtVisible(); } } private void AbortInShopSession(bool resetShopWindow) { if (_active) { MerchantStackerPlugin.Log.LogInfo((object)"In-shop qty aborted (shop closed/disabled)"); PurchaseBatcher.ClearPendingQuantity(); PurchaseBatcher.ExpectingFsmPurchase = false; PurchaseBatcher.ClearShopPurchaseSuppression(); Action shopCancel = _shopCancel; _purchaseDone = null; _shopCancel = null; _active = false; _hijacked = false; _inShop = false; _shopRoot = null; _shopStats = null; DestroyInShopHud(restoreTexts: true); ResetHoldState(); InventoryPaneInput.IsInputBlocked = false; if (resetShopWindow) { shopCancel?.Invoke(); } } } public void Hijack(DialogueYesNoBox box, string title, CollectableItem? item, int unitCost, CurrencyType currency, int maxQuantity, Action? originalYes, Action? originalNo) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (MerchantStackerPlugin.Enabled.Value && maxQuantity >= 1 && !_active) { BeginSession(title, item, unitCost, currency, maxQuantity, hijacked: true); _inShop = false; _originalYes = originalYes; _originalNo = originalNo; _onConfirm = null; _onCancel = null; _purchaseDone = null; _shopCancel = null; CurrentYesField.SetValue(box, (Action)delegate { Finish(confirmed: true); }); CurrentNoField.SetValue(box, (Action)delegate { Finish(confirmed: false); }); EnsureWillGetDisplay(box, item); ((MonoBehaviour)this).StartCoroutine(RefreshAfterOpen()); MerchantStackerPlugin.Log.LogInfo((object)$"Hijack DialogueYesNoBox: {_title} max={_max} cost={_unitCost}"); } } public void Open(string title, CollectableItem? item, int unitCost, CurrencyType currency, int maxQuantity, Action<int> onConfirm, Action onCancel) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) if (!MerchantStackerPlugin.Enabled.Value || maxQuantity < 1) { onConfirm(1); return; } BeginSession(title, item, unitCost, currency, maxQuantity, hijacked: false); _inShop = false; _onConfirm = onConfirm; _onCancel = onCancel; _originalYes = null; _originalNo = null; _purchaseDone = null; _shopCancel = null; SuppressHijack = true; try { DialogueYesNoBox.Open((Action)delegate { Finish(confirmed: true); }, (Action)delegate { Finish(confirmed: false); }, true, _title, _currency, _unitCost, (IReadOnlyList<SavedItem>)null, (IReadOnlyList<int>)null, true, false, (SavedItem)(object)_item, (TakeItemTypes)0, (DisplayType)1); } finally { SuppressHijack = false; } ((MonoBehaviour)this).StartCoroutine(RefreshAfterOpen()); MerchantStackerPlugin.Log.LogInfo((object)$"Native qty open: {_title} max={_max} cost={_unitCost}"); } private void BeginSession(string title, CollectableItem? item, int unitCost, CurrencyType currency, int maxQuantity, bool hijacked) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) _title = (string.IsNullOrEmpty(title) ? "Buy" : title); _item = item; _unitCost = Math.Max(1, unitCost); _currency = currency; _min = 1; _max = Math.Max(1, maxQuantity); _quantity = 1; _hijacked = hijacked; _inShop = false; _shopRoot = null; _shopStats = null; _active = true; ResetHoldState(); InventoryPaneInput.IsInputBlocked = true; } private void BindShopCostText(ShopItemStats stats) { _boundCostText = null; _originalCostText = null; _boundStock = null; _originalShopTitle = null; try { object? obj = ItemCostTextField?.GetValue(stats); TextMeshPro val = (TextMeshPro)((obj is TextMeshPro) ? obj : null); if (val != null) { _boundCostText = val; _originalCostText = ((TMP_Text)val).text; } _boundStock = ((Component)stats).GetComponentInParent<ShopMenuStock>(); if ((Object)(object)_boundStock != (Object)null) { _originalShopTitle = _boundStock.Title; } } catch { } } private void BuildConfirmQtyHud() { //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Expected O, but got Unknown //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_032e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_hudRoot != (Object)null || (Object)(object)_shopStats == (Object)null) { return; } ShopConfirmShowPatches.BuildingQtyHud = true; try { Transform root = ((Component)_shopStats).transform.root; Transform val = FindNamedTransform(root, "Item Confirm Group"); Transform val2 = FindNamedTransform(root, "Confirm"); if ((Object)(object)val2 == (Object)null) { MerchantStackerPlugin.Log.LogWarning((object)"Qty HUD: Confirm transform not found"); return; } TextMeshPro val3 = FindTemplateTmp(val2) ?? _boundCostText; if ((Object)(object)val3 == (Object)null) { MerchantStackerPlugin.Log.LogWarning((object)"Qty HUD: no TMP template"); return; } Transform val4 = (((Object)(object)val != (Object)null) ? val : val2); EnsureConfirmItemArtVisible(); GetQtyRowLocal(val4, out _qtyLocal, out _arrowUpLocal, out _arrowDownLocal, out _currencyLocal, out _costLocal); _hudRoot = new GameObject("MerchantStacker_QtyHud"); _hudRoot.layer = ((Component)val4).gameObject.layer; _hudRoot.transform.SetParent(val4, false); _hudRoot.transform.localPosition = Vector3.zero; _hudRoot.transform.localRotation = Quaternion.identity; _hudRoot.transform.localScale = Vector3.one; TextMeshPro val5 = FindConfirmCostTmp(val2) ?? val3; float num = Math.Max(5f, ((TMP_Text)val5).fontSize); _hudQty = CloneTmpLocal(val3, _hudRoot.transform, "Qty", _qtyLocal, "1", num * 2.7f, (TextAlignmentOptions)5); _hudCost = CloneTmpLocal(val5, _hudRoot.transform, "TotalCost", _costLocal, "0", num * 2f, (TextAlignmentOptions)4); object? obj = CostSpriteField?.GetValue(_shopStats); SpriteRenderer val6 = (SpriteRenderer)((obj is SpriteRenderer) ? obj : null); if ((Object)(object)val6 != (Object)null) { _hudCurrencyIcon = CloneSpriteLocal(val6, _hudRoot.transform, "CurrencyIcon", _currencyLocal, 2f); Sprite currencySprite = _shopStats.GetCurrencySprite(); if ((Object)(object)currencySprite != (Object)null) { _hudCurrencyIcon.sprite = currencySprite; } } if (TryCreateVerticalArrowsLocal(val2, val4, _hudRoot.transform, _arrowUpLocal, _arrowDownLocal)) { MerchantStackerPlugin.Log.LogInfo((object)"Qty HUD arrows: ok"); } else { MerchantStackerPlugin.Log.LogWarning((object)"Qty HUD: no arrow templates found"); } HideConfirmChrome(val2, val); HideNativeConfirmCosts(val2); CacheChromeToKeepOff(val2, val); _lastHudQty = int.MinValue; _lastHudTotal = int.MinValue; _lastArrowUpOn = _quantity >= _max; _lastArrowDownOn = _quantity <= _min; MatchArrowDrawOrderToQty(); RefreshInShopHud(); ReassertHudPoses(); ForceArrowRenderersOn(); MerchantStackerPlugin.Log.LogInfo((object)($"Qty HUD row qty={_qtyLocal} cost={_costLocal} arrows={(Object)(object)_hudArrowUp != (Object)null} " + $"arrowSize={MeshSize(_hudArrowUp)}")); } catch (Exception ex) { MerchantStackerPlugin.Log.LogWarning((object)("Qty HUD build failed: " + ex.Message)); DestroyInShopHud(restoreTexts: true); } finally { ShopConfirmShowPatches.BuildingQtyHud = false; } } private void HideNativeConfirmCosts(Transform confirm) { _hiddenNativeCost.Clear(); Transform[] componentsInChildren = ((Component)confirm).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if ((Object)(object)val == (Object)null) { continue; } string name = ((Object)val).name; if (!(name != "Costs") || !(name != "Money") || !(name != "Item cost") || !(name != "Geo Sprite")) { MeshRenderer[] componentsInChildren2 = ((Component)val).GetComponentsInChildren<MeshRenderer>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { ((Renderer)componentsInChildren2[j]).enabled = false; } SpriteRenderer[] componentsInChildren3 = ((Component)val).GetComponentsInChildren<SpriteRenderer>(true); for (int j = 0; j < componentsInChildren3.Length; j++) { ((Renderer)componentsInChildren3[j]).enabled = false; } if (((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(false); } _hiddenNativeCost.Add(((Component)val).gameObject); } } } private static TextMeshPro? FindConfirmCostTmp(Transform confirm) { TextMeshPro[] componentsInChildren = ((Component)confirm).GetComponentsInChildren<TextMeshPro>(true); foreach (TextMeshPro val in componentsInChildren) { if ((Object)(object)val != (Object)null && ((Object)((Component)val).gameObject).name == "Item cost") { return val; } } return null; } private static void GetQtyRowLocal(Transform layoutParent, out Vector3 qtyLocal, out Vector3 upLocal, out Vector3 downLocal, out Vector3 currencyLocal, out Vector3 costLocal) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) Vector3 localPosition = default(Vector3); ((Vector3)(ref localPosition))..ctor(-3.4f, 1.5f, -3f); foreach (Transform item in layoutParent) { Transform val = item; if ((Object)(object)val != (Object)null && ((Object)val).name == "Item Sprite") { localPosition = val.localPosition; break; } } float z = localPosition.z; float num = localPosition.y - 3.5f; float num2 = localPosition.x - 0.85f; qtyLocal = new Vector3(num2 - 0.9f, num, z); upLocal = new Vector3(qtyLocal.x, num + 1.1f, z); downLocal = new Vector3(qtyLocal.x, num - 1.1f, z); currencyLocal = new Vector3(num2 + 0.85f, num, z); costLocal = new Vector3(num2 + 1.55f, num, z); } private bool TryCreateVerticalArrowsLocal(Transform confirm, Transform layoutParent, Transform arrowParent, Vector3 upLocal, Vector3 downLocal) { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) SpriteRenderer val = (SpriteRenderer)(((object)_hudCurrencyIcon) ?? ((object)/*isinst with value type is only supported in some contexts*/)); EnsureArrowSpriteCached(); if ((Object)(object)_cachedArrowSprite != (Object)null && (Object)(object)val != (Object)null) { _hudArrowUp = CloneSpriteCaret(val, arrowParent, "ArrowUp", upLocal, 90f, 2f); _hudArrowDown = CloneSpriteCaret(val, arrowParent, "ArrowDown", downLocal, 270f, 2f); ApplySprite(_hudArrowUp, _cachedArrowSprite); ApplySprite(_hudArrowDown, _cachedArrowSprite); RememberArrowBaseScales(); MerchantStackerPlugin.Log.LogInfo((object)$"Arrows from sprite '{((Object)_cachedArrowSprite).name}' size={SpriteSize(_hudArrowUp)}"); return true; } if ((Object)(object)val != (Object)null && (Object)(object)val.sprite != (Object)null) { _hudArrowUp = CloneSpriteCaret(val, arrowParent, "ArrowUp", upLocal, 90f, 2f); _hudArrowDown = CloneSpriteCaret(val, arrowParent, "ArrowDown", downLocal, 270f, 2f); RememberArrowBaseScales(); MerchantStackerPlugin.Log.LogInfo((object)$"Arrows from currency sprite '{((Object)val.sprite).name}' size={SpriteSize(_hudArrowUp)}"); return true; } EnsureCaretMeshCached(confirm, layoutParent); if ((Object)(object)_cachedCaretMesh != (Object)null && (Object)(object)_cachedCaretMaterial != (Object)null) { _hudArrowUp = CreateMeshCaret(arrowParent, "ArrowUp", upLocal, 90f, 0.9f); _hudArrowDown = CreateMeshCaret(arrowParent, "ArrowDown", downLocal, -90f, 0.9f); RememberArrowBaseScales(); MerchantStackerPlugin.Log.LogInfo((object)$"Arrows from tk2d caret mesh size={MeshSize(_hudArrowUp)}"); if ((Object)(object)_hudArrowUp != (Object)null) { return (Object)(object)_hudArrowDown != (Object)null; } return false; } return false; } private static void EnsureCaretMeshCached(Transform confirm, Transform layoutParent) { //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0217: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_02cd: Unknown result type (might be due to invalid IL or missing references) //IL_02d2: Unknown result type (might be due to invalid IL or missing references) //IL_02d6: Unknown result type (might be due to invalid IL or missing references) //IL_0246: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_cachedCaretMesh != (Object)null && (Object)(object)_cachedCaretMaterial != (Object)null) { return; } GameObject val = null; Transform val2 = FindNamedTransform(confirm, "Pointer L") ?? FindNamedTransform(layoutParent, "Pointer L"); if ((Object)(object)val2 != (Object)null) { Transform parent = val2.parent; while ((Object)(object)parent != (Object)null && ((Object)parent).name != "Yes" && ((Object)parent).name != "Confirm") { parent = parent.parent; } if ((Object)(object)parent != (Object)null && ((Object)parent).name == "Yes" && !((Component)parent).gameObject.activeSelf) { ((Component)parent).gameObject.SetActive(true); } ((Component)val2).gameObject.SetActive(true); InvAnimateUpAndDown component = ((Component)val2).GetComponent<InvAnimateUpAndDown>(); if (component != null) { component.Show(); } val = ((Component)val2).gameObject; } if ((Object)(object)val == (Object)null) { ScrollView[] array = Resources.FindObjectsOfTypeAll<ScrollView>(); foreach (ScrollView val3 in array) { if ((Object)(object)val3 == (Object)null) { continue; } Scene scene = ((Component)val3).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { continue; } object? obj = ScrollUpArrowField?.GetValue(val3); Component val4 = (Component)((obj is Component) ? obj : null); if (!((Object)(object)val4 == (Object)null)) { val4.gameObject.SetActive(true); Component obj2 = ((val4 is InvAnimateUpAndDown) ? val4 : null); if (obj2 != null) { ((InvAnimateUpAndDown)obj2).Show(); } val = val4.gameObject; break; } } } if ((Object)(object)val == (Object)null) { return; } MeshFilter componentInChildren = val.GetComponentInChildren<MeshFilter>(true); MeshRenderer componentInChildren2 = val.GetComponentInChildren<MeshRenderer>(true); if ((Object)(object)componentInChildren == (Object)null || (Object)(object)componentInChildren2 == (Object)null || (Object)(object)componentInChildren.sharedMesh == (Object)null || (Object)(object)((Renderer)componentInChildren2).sharedMaterial == (Object)null) { MerchantStackerPlugin.Log.LogWarning((object)$"Caret bake skipped: mesh={(Object)(object)((componentInChildren != null) ? componentInChildren.sharedMesh : null) != (Object)null} mat={(Object)(object)((componentInChildren2 != null) ? ((Renderer)componentInChildren2).sharedMaterial : null) != (Object)null}"); return; } Bounds bounds = componentInChildren.sharedMesh.bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (Mathf.Max(size.x, size.y) < 0.08f) { MerchantStackerPlugin.Log.LogInfo((object)$"Caret bake skipped: mesh too small ({size})"); return; } _cachedCaretMesh = Object.Instantiate<Mesh>(componentInChildren.sharedMesh); ((Object)_cachedCaretMesh).name = "MerchantStacker_CaretMesh"; _cachedCaretMaterial = ((Renderer)componentInChildren2).sharedMaterial; _cachedCaretSortLayer = ((Renderer)componentInChildren2).sortingLayerID; _cachedCaretSortOrder = Math.Max(((Renderer)componentInChildren2).sortingOrder + 20, 260); ManualLogSource log = MerchantStackerPlugin.Log; string text = $"Cached tk2d caret mesh verts={_cachedCaretMesh.vertexCount} "; bounds = _cachedCaretMesh.bounds; log.LogInfo((object)(text + $"bounds={((Bounds)(ref bounds)).size}")); } private static void EnsureArrowSpriteCached() { //IL_0031: 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_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0172: Unknown result type (might be due to invalid IL or missing references) if (_arrowAssetsSearched) { return; } _arrowAssetsSearched = true; InventoryArrowContainer[] array = Resources.FindObjectsOfTypeAll<InventoryArrowContainer>(); foreach (InventoryArrowContainer val in array) { if ((Object)(object)val == (Object)null) { continue; } Scene scene = ((Component)val).gameObject.scene; if (!((Scene)(ref scene)).IsValid()) { continue; } SpriteRenderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<SpriteRenderer>(true); foreach (SpriteRenderer val2 in componentsInChildren) { if ((Object)(object)((val2 != null) ? val2.sprite : null) != (Object)null && LooksLikeArrowSprite(((Object)val2.sprite).name, ((Object)((Component)val2).gameObject).name)) { _cachedArrowSprite = val2.sprite; MerchantStackerPlugin.Log.LogInfo((object)("Cached arrow sprite from InventoryArrowContainer '" + ((Object)val2.sprite).name + "'")); return; } } } Sprite[] array2 = Resources.FindObjectsOfTypeAll<Sprite>(); foreach (Sprite val3 in array2) { if ((Object)(object)val3 == (Object)null || !LooksLikeArrowSprite(((Object)val3).name, ((Object)val3).name)) { continue; } Rect rect = val3.rect; if (!(((Rect)(ref rect)).width > 128f)) { rect = val3.rect; if (!(((Rect)(ref rect)).height > 128f)) { _cachedArrowSprite = val3; ManualLogSource log = MerchantStackerPlugin.Log; string name = ((Object)val3).name; rect = val3.rect; object arg = ((Rect)(ref rect)).width; rect = val3.rect; log.LogInfo((object)$"Cached arrow sprite '{name}' ({arg}x{((Rect)(ref rect)).height})"); break; } } } } private static bool LooksLikeArrowSprite(string spriteName, string goName) { string haystack = spriteName + " " + goName; if (ContainsIgnore(haystack, "map") || ContainsIgnore(haystack, "quest") || ContainsIgnore(haystack, "pan") || ContainsIgnore(haystack, "compass") || ContainsIgnore(haystack, "marker")) { return false; } if (!ContainsIgnore(haystack, "arrow") && !ContainsIgnore(haystack, "caret") && !ContainsIgnore(haystack, "chevron")) { return ContainsIgnore(haystack, "pointer"); } return true; } private static GameObject CreateMeshCaret(Transform parent, string name, Vector3 localPos, float rotationZ, float scale) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_002b: 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) //IL_0052: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.layer = ((Component)parent).gameObject.layer; val.transform.SetParent(parent, false); val.transform.localPosition = localPos; val.transform.localRotation = Quaternion.Euler(0f, 0f, rotationZ); val.transform.localScale = Vector3.one * scale; val.AddComponent<MeshFilter>().sharedMesh = _cachedCaretMesh; MeshRenderer val2 = val.AddComponent<MeshRenderer>(); ((Renderer)val2).sharedMaterial = _cachedCaretMaterial; ((Renderer)val2).sortingLayerID = _cachedCaretSortLayer; ((Renderer)val2).sortingOrder = _cachedCaretSortOrder; ((Renderer)val2).enabled = true; Bounds bounds = ((Renderer)val2).bounds; float x = ((Bounds)(ref bounds)).size.x; bounds = ((Renderer)val2).bounds; float num = Mathf.Max(x, ((Bounds)(ref bounds)).size.y); if (num > 0.0001f && num < 0.5f) { Transform transform = val.transform; transform.localScale *= 0.8f / num; } return val; } private static void ApplySprite(GameObject? go, Sprite sprite) { if (!((Object)(object)go == (Object)null)) { SpriteRenderer component = go.GetComponent<SpriteRenderer>(); if ((Object)(object)component != (Object)null) { component.sprite = sprite; ((Renderer)component).enabled = true; } } } private void RememberArrowBaseScales() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_006a: 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) if ((Object)(object)_hudArrowUp != (Object)null) { _arrowUpBaseLocalScale = _hudArrowUp.transform.localScale; _arrowUpLocalRot = _hudArrowUp.transform.localRotation; } if ((Object)(object)_hudArrowDown != (Object)null) { _arrowDownBaseLocalScale = _hudArrowDown.transform.localScale; _arrowDownLocalRot = _hudArrowDown.transform.localRotation; } } private void DestroyArrowPair() { if ((Object)(object)_hudArrowUp != (Object)null) { Object.Destroy((Object)(object)_hudArrowUp); _hudArrowUp = null; } if ((Object)(object)_hudArrowDown != (Object)null) { Object.Destroy((Object)(object)_hudArrowDown); _hudArrowDown = null; } } private static Vector3 MeshSize(GameObject? go) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)go == (Object)null) { return Vector3.zero; } MeshRenderer componentInChildren = go.GetComponentInChildren<MeshRenderer>(true); if ((Object)(object)componentInChildren != (Object)null) { Bounds bounds = ((Renderer)componentInChildren).bounds; return ((Bounds)(ref bounds)).size; } return SpriteSize(go); } private static Vector3 SpriteSize(GameObject? go) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)go == (Object)null) { return Vector3.zero; } SpriteRenderer componentInChildren = go.GetComponentInChildren<SpriteRenderer>(true); if (!((Object)(object)componentInChildren != (Object)null)) { return Vector3.zero; } Bounds bounds = ((Renderer)componentInChildren).bounds; return ((Bounds)(ref bounds)).size; } private static GameObject CloneSpriteCaret(SpriteRenderer template, Transform parent, string name, Vector3 localPos, float rotationZ, float scaleMul) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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) GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject, parent); ((Object)val).name = name; val.layer = ((Component)parent).gameObject.layer; val.SetActive(true); val.transform.localPosition = localPos; val.transform.localRotation = Quaternion.Euler(0f, 0f, rotationZ); val.transform.localScale = Vector3.one * scaleMul; for (int num = val.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)val.transform.GetChild(num)).gameObject); } SpriteRenderer component = val.GetComponent<SpriteRenderer>(); if ((Object)(object)component != (Object)null) { ((Renderer)component).enabled = true; Color color = component.color; color.a = 1f; component.color = color; ((Renderer)component).sortingOrder = Math.Max(((Renderer)template).sortingOrder + 10, 260); ((Renderer)component).sortingLayerID = ((Renderer)template).sortingLayerID; } return val; } private void MatchArrowDrawOrderToQty() { if ((Object)(object)_hudQty == (Object)null) { return; } MeshRenderer component = ((Component)_hudQty).GetComponent<MeshRenderer>(); if ((Object)(object)component == (Object)null) { return; } GameObject[] array = (GameObject[])(object)new GameObject[2] { _hudArrowUp, _hudArrowDown }; foreach (GameObject val in array) { if (!((Object)(object)val == (Object)null)) { MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer obj in componentsInChildren) { ((Renderer)obj).enabled = true; ((Renderer)obj).sortingLayerID = ((Renderer)component).sortingLayerID; ((Renderer)obj).sortingOrder = ((Renderer)component).sortingOrder + 5; } SpriteRenderer[] componentsInChildren2 = val.GetComponentsInChildren<SpriteRenderer>(true); foreach (SpriteRenderer obj2 in componentsInChildren2) { ((Renderer)obj2).enabled = true; ((Renderer)obj2).sortingLayerID = ((Renderer)component).sortingLayerID; ((Renderer)obj2).sortingOrder = ((Renderer)component).sortingOrder + 5; } } } } private void ForceArrowRenderersOn() { GameObject[] array = (GameObject[])(object)new GameObject[2] { _hudArrowUp, _hudArrowDown }; foreach (GameObject val in array) { if (!((Object)(object)val == (Object)null)) { if (!val.activeSelf) { val.SetActive(true); } MeshRenderer[] componentsInChildren = val.GetComponentsInChildren<MeshRenderer>(true); for (int j = 0; j < componentsInChildren.Length; j++) { ((Renderer)componentsInChildren[j]).enabled = true; } SpriteRenderer[] componentsInChildren2 = val.GetComponentsInChildren<SpriteRenderer>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { ((Renderer)componentsInChildren2[j]).enabled = true; } } } } private void HideConfirmChrome(Transform confirm, Transform? confirmGroup) { object obj = (((Object)(object)confirmGroup != (Object)null) ? ((object)confirmGroup) : ((object)confirm)); ShopConfirmListPatches.SuppressConfirmChromePublic((Transform)obj); Transform val = confirm.Find("UI List"); if ((Object)(object)val != (Object)null) { _hiddenConfirmList = ((Component)val).gameObject; if (((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(false); } } Transform val2 = FindNamedTransform(confirm, "Confirm msg"); if ((Object)(object)val2 != (Object)null) { _hiddenConfirmMsg = ((Component)val2).gameObject; if (((Component)val2).gameObject.activeSelf) { ((Component)val2).gameObject.SetActive(false); } } Transform[] componentsInChildren = ((Component)obj).GetComponentsInChildren<Transform>(true); foreach (Transform val3 in componentsInChildren) { if (!((Object)(object)val3 == (Object)null)) { string name = ((Object)val3).name; if ((ContainsIgnore(name, "cursor") || ContainsIgnore(name, "selector")) && ((Component)val3).gameObject.activeSelf) { ((Component)val3).gameObject.SetActive(false); } } } } private static bool ContainsIgnore(string haystack, string needle) { return haystack.IndexOf(needle, StringComparison.OrdinalIgnoreCase) >= 0; } private IEnumerator EnsureHudSoon() { yield return null; if (_active && _inShop) { ReassertHudPoses(); MatchArrowDrawOrderToQty(); ForceArrowRenderersOn(); RefreshInShopHud(); } } private void RefreshInShopHud() { //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) int num = _unitCost * _quantity; bool flag = _quantity != _lastHudQty; bool flag2 = num != _lastHudTotal; _lastHudQty = _quantity; _lastHudTotal = num; ApplyTmp(_hudQty, _quantity.ToString(CultureInfo.InvariantCulture), flag || flag2); ApplyTmp(_hudCost, num.ToString(CultureInfo.InvariantCulture), force: true); if ((Object)(object)_shopStats != (Object)null && (_hiddenNativeCost.Count > 0 || flag2)) { KeepNativeConfirmCostsHidden(); } bool flag3 = _quantity < _max; bool flag4 = _quantity > _min; if (flag3 != _lastArrowUpOn || flag) { _lastArrowUpOn = flag3; SetArrowVisible(_hudArrowUp, flag3, _arrowUpBaseLocalScale); } if (flag4 != _lastArrowDownOn || flag) { _lastArrowDownOn = flag4; SetArrowVisible(_hudArrowDown, flag4, _arrowDownBaseLocalScale); } if ((Object)(object)_hudCurrencyIcon != (Object)null) { ((Renderer)_hudCurrencyIcon).enabled = true; if (!((Component)_hudCurrencyIcon).gameObject.activeSelf) { ((Component)_hudCurrencyIcon).gameObject.SetActive(true); } } } private static void SetArrowVisible(GameObject? arrow, bool fullyVisible, Vector3 baseLocalScale) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)arrow == (Object)null)) { arrow.transform.localScale = baseLocalScale * (fullyVisible ? 1f : 0.55f); MeshRenderer[] componentsInChildren = arrow.GetComponentsInChildren<MeshRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ((Renderer)componentsInChildren[i]).enabled = true; } SpriteRenderer[] componentsInChildren2 = arrow.GetComponentsInChildren<SpriteRenderer>(true); for (int i = 0; i < componentsInChildren2.Length; i++) { ((Renderer)componentsInChildren2[i]).enabled = true; } } } private void ReassertHudPoses() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0136: 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) //IL_0152: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_hudQty != (Object)null) { SetLocalPose(_hudQty.transform, _qtyLocal, Vector3.one); } if ((Object)(object)_hudCost != (Object)null) { SetLocalPose(_hudCost.transform, _costLocal, Vector3.one); } if ((Object)(object)_hudCurrencyIcon != (Object)null) { SetLocalPose(((Component)_hudCurrencyIcon).transform, _currencyLocal, ((Component)_hudCurrencyIcon).transform.localScale); } if ((Object)(object)_hudArrowUp != (Object)null) { float num = (_lastArrowUpOn ? 1f : 0.55f); _hudArrowUp.transform.localPosition = _arrowUpLocal; _hudArrowUp.transform.localRotation = _arrowUpLocalRot; _hudArrowUp.transform.localScale = _arrowUpBaseLocalScale * num; } if ((Object)(object)_hudArrowDown != (Object)null) { float num2 = (_lastArrowDownOn ? 1f : 0.55f); _hudArrowDown.transform.localPosition = _arrowDownLocal; _hudArrowDown.transform.localRotation = _arrowDownLocalRot; _hudArrowDown.transform.localScale = _arrowDownBaseLocalScale * num2; } } private static void ApplyTmp(TextMeshPro? tmp, string value, bool force = false) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: 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_004c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)tmp == (Object)null) { return; } try { if (!((Component)tmp).gameObject.activeSelf) { ((Component)tmp).gameObject.SetActive(true); } ((Behaviour)tmp).enabled = true; Color color = ((Graphic)tmp).color; if (color.a < 0.9f) { color.a = 1f; ((Graphic)tmp).color = color; } string text = ((TMP_Text)tmp).text ?? string.Empty; if (force || !string.Equals(text.Trim(), value, StringComparison.Ordinal)) { ((TMP_Text)tmp).text = value; ((TMP_Text)tmp).SetText(value); ((TMP_Text)tmp).ForceMeshUpdate(true); } MeshRenderer component = ((Component)tmp).GetComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null) { ((Renderer)component).enabled = true; } } catch { } } private void KeepNativeConfirmCostsHidden() { for (int i = 0; i < _hiddenNativeCost.Count; i++) { GameObject val = _hiddenNativeCost[i]; if ((Object)(object)val != (Object)null && val.activeSelf) { val.SetActive(false); } } } private static void SetTmpAlpha(TextMeshPro? tmp, float alpha) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)tmp == (Object)null)) { Color color = ((Graphic)tmp).color; color.a = alpha; ((Graphic)tmp).color = color; } } private static void SetLocalPose(Transform t, Vector3 localPos, Vector3 localScale) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) t.localPosition = localPos; t.localRotation = Quaternion.identity; t.localScale = localScale; RectTransform val = (RectTransform)(object)((t is RectTransform) ? t : null); if (val != null) { val.anchoredPosition3D = localPos; } } private static TextMeshPro CloneTmpLocal(TextMeshPro template, Transform parent, string name, Vector3 localPos, string text, float fontSize, TextAlignmentOptions alignment = (TextAlignmentOptions)5) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(((Component)template).gameObject); ((Object)val).name = name; val.transform.SetParent(parent, false); val.SetActive(true); SetLocalPose(val.transform, localPos, Vector3.one); for (int num = val.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)val.transform.GetChild(num)).gameObject); } TextMeshPro component = val.GetComponent<TextMeshPro>(); ((Behaviour)component).enabled = true; ((TMP_Text)component).fontSize = fontSize; ((TMP_Text)component).alignment = alignment; ((TMP_Text)component).enableWordWrapping = false; Color color = ((Graphic)template).color; color.a = 1f; ((Graphic)component).color = color; ((TMP_Text)component).SetText(text); ((TMP_Text)component).ForceMeshUpdate(true); MeshRenderer component2 = val.GetComponent<MeshRenderer>(); if ((Object)(object)component2 != (Object)null) { ((Renderer)component2).enabled = true; ((Renderer)component2).sortingOrder = Math.Max(((Renderer)component2).sortingOrder, 250); } return component; } private static SpriteRenderer CloneSpriteLocal(SpriteRenderer template, Transform parent, string name, Vector3 localPos, float scaleMul) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) GameObject obj = Object.Instantiate<GameObject>(((Component)template).gameObject); ((Object)obj).name = name; obj.transform.SetParent(parent, false); obj.SetActive(true); SetLocalPose(obj.transform, localPos, ((Component)template).transform.localScale * scaleMul); SpriteRenderer component = obj.GetComponent<SpriteRenderer>(); ((Renderer)component).enabled = true; Color color = component.color; color.a = 1f; component.color = color; ((Renderer)component).sortingOrder = Math.Max(((Renderer)component).sortingOrder, 250); return component; } private static Transform? FindNamedTransform(Transform root, string name) { Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if ((Object)(object)val != (Object)null && ((Object)val).name == name) { return val; } } return null; } private static TextMeshPro? FindTemplateTmp(Transform confirm) { TextMeshPro[] componentsInChildren = ((Component)confirm).GetComponentsInChildren<TextMeshPro>(true); foreach (TextMeshPro val in componentsInChildren) { if ((Object)(object)val != (Object)null && ((Object)((Component)val).gameObject).name == "Text" && (Object)(object)val.transform.parent != (Object)null && ((Object)val.transform.parent).name == "Yes") { return val; } } componentsInChildren = ((Component)confirm).GetComponentsInChildren<TextMeshPro>(true); foreach (TextMeshPro val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null) { return val2; } } return null; } private static void ForceHideConfirmChromeOnly(ShopItemStats? stats) { Transform val = null; try { if ((Object)(object)stats != (Object)null) { val = ((Component)stats).transform.root; } } catch { val = null; } if ((Object)(object)val == (Object)null) { ShopMenuStock[] array = Object.FindObjectsByType<ShopMenuStock>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (ShopMenuStock val2 in array) { if (ShopConfirmListPatches.IsLiveOpenShopStock(val2)) { val = ((Component)val2).transform.root; break; } } } if ((Object)(object)val == (Object)null) { return; } ShopConfirmListPatches.RestoreConfirmChromePublic(); ShopConfirmListPatches.ForceEnableConfirmYesNoPublic(); Transform[] componentsInChildren = ((Component)val).GetComponentsInChildren<Transform>(true); foreach (Transform val3 in componentsInChildren) { if ((Object)(object)val3 == (Object)null || ((Object)val3).name != "Item Confirm Group") { continue; } Transform[] componentsInChildren2 = ((Component)val3).GetComponentsInChildren<Transform>(true); foreach (Transform val4 in componentsInChildren2) { if ((Object)(object)val4 == (Object)null) { continue; } string name = ((Object)val4).name; if (!(name == "UI List") || !((Object)(object)val4.parent != (Object)null) || !(((Object)val4.parent).name == "Confirm")) { switch (name) { case "Yes": case "No": case "Confirm msg": case "Costs": break; default: continue; } } if (!((Component)val4).gameObject.activeSelf) { ((Component)val4).gameObject.SetActive(true); } } if (((Component)val3).gameObject.activeSelf) { ((Component)val3).gameObject.SetActive(false); } } } private void DestroyInShopHud(bool restoreTexts, bool restoreConfirmChrome = true) { if (restoreTexts) { if ((Object)(object)_boundStock != (Object)null && _originalShopTitle != null) { _boundStock.Title = _originalShopTitle; } if ((Object)(object)_boundCostText != (Object)null && _originalCostText != null) { ApplyTmp(_boundCostText, _originalCostText); } } ClearTmpVisual(_hudQty); ClearTmpVisual(_hudCost); if ((Object)(object)_hudRoot != (Object)null) { Object.DestroyImmediate((Object)(object)_hudRoot); } _hudRoot = null; _hudQty = null; _hudArrowUp = null; _hudArrowDown = null; _hudCost = null; _hudCurrencyIcon = null; _chromeToKeepOff.Clear(); ShopConfirmShowPatches.LockConfirmChrome = false; _itemArtSprite = null; _itemArtName = null; _itemArtSpriteSr = null; _itemArtNameTmp = null; _itemArtNameMr = null; ScrubLeftoverQtyHud(); if (restoreConfirmChrome) { if ((Object)(object)_hiddenConfirmList != (Object)null) { _hiddenConfirmList.SetActive(true); _hiddenConfirmList = null; } if ((Object)(object)_hiddenConfirmMsg != (Object)null) { _hiddenConfirmMsg.SetActive(true); _hiddenConfirmMsg = null; } foreach (GameObject item in _hiddenNativeCost) { if ((Object)(object)item == (Object)null) { continue; } TextMeshPro[] componentsInChildren = item.GetComponentsInChildren<TextMeshPro>(true); foreach (TextMeshPro val in componentsInChildren) { if ((Object)(object)val != (Object)null && ((Object)((Component)val).gameObject).name == "Item cost" && _unitCost > 0) { ApplyTmp(val, _unitCost.ToString(CultureInfo.InvariantCulture)); } } item.SetActive(true); } _hiddenNativeCost.Clear(); } else { _hiddenConfirmList = null; _hiddenConfirmMsg = null; _hiddenNativeCost.Clear(); } if (restoreTexts) { _boundStock = null; _originalShopTitle = null; _boundCostText = null; _originalCostText = null; } } private static void ClearTmpVisual(TextMeshPro? tmp) { if ((Object)(object)tmp == (Object)null) { return; } try { ((TMP_Text)tmp).SetText(string.Empty); ((TMP_Text)tmp).ForceMeshUpdate(true); MeshRenderer component = ((Component)tmp).GetComponent<MeshRenderer>(); if ((Object)(object)component != (Object)null) { ((Renderer)component).enabled = false; } } catch { } } private static void ScrubLeftoverQtyHud() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Invalid comparison between Unknown and I4 GameObject[] array = Resources.FindObjectsOfTypeAll<GameObject>(); foreach (GameObject val in array) { if ((Object)(object)val == (Object)null) { continue; } bool flag; try { Scene scene = val.scene; flag = ((Scene)(ref scene)).IsValid() || (int)((Object)val).hideFlags > 0; } catch { continue; } if ((flag || !(((Object)val).name != "MerchantStacker_QtyHud")) && (((Object)val).name == "MerchantStacker_QtyHud" || ((Object)val).name == "TotalCost" || ((Object)val).name == "Qty" || ((Object)val).name == "ArrowUp" || ((Object)val).name == "ArrowDown" || ((Object)val).name == "CurrencyIcon") && (((Object)val).name == "MerchantStacker_QtyHud" || ((Object)(object)val.transform.parent != (Object)null && (((Object)val.transform.parent).name == "MerchantStacker_QtyHud" || ((Object)val.transform.parent).name == "MerchantStacker_QuantityPicker" || (((Object)val).name == "MerchantStacker_QtyHud" && ((Object)val.transform.parent).name == "Item Confirm Group"))))) { TextMeshPro[] componentsInChildren = val.GetComponentsInChildren<TextMeshPro>(true); for (int j = 0; j < componentsInChildren.Length; j++) { ClearTmpVisual(componentsInChildren[j]); } Object.DestroyImmediate((Object)(object)val); } } } private void ClearPickerHudChildren() { for (int num = ((Component)this).transform.childCount - 1; num >= 0; num--) { Transform child = ((Component)this).transform.GetChild(num); if (!((Object)(object)child == (Object)null)) { TextMeshPro[] componentsInChildren = ((Component)child).GetComponentsInChildren<TextMeshPro>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ClearTmpVisual(componentsInChildren[i]); } Object.DestroyImmediate((Object)(object)((Component)child).gameObject); } } _hudRoot = null; _hudQty = null; _hudArrowUp = null; _hudArrowDown = null; _hudCost = null; _hudCurrencyIcon = null; } private IEnumerator RefreshAfterOpen() { yield return null; yield return null; if (_active && !_inShop) { RefreshNativeDisplay(); } } private static void CompleteInShopPurchase(ShopItemStats shopStats, int qty, Action? purchaseDone) { ShopMenuStock stock = ((Component)shopStats).GetComponentInParent<ShopMenuStock>(); PurchaseBatcher.ClearPendingQuantity(); PurchaseBatcher.ExpectingFsmPurchase = false; PurchaseBatcher.BuyShopItem(shopStats, qty, 0, delegate { ShopMenuStock obj = stock; if (obj != null) { obj.SetWasItemPurchased(true); } ShowPurchaseFeedback(shopStats); ScrubLeftoverQtyHud(); ForceHideConfirmChromeOnly(shopStats); purchaseDone?.Invoke(); EventRegister.SendEvent(EventRegisterEvents.ResetShopWindow, (GameObject)null); PurchaseBatcher.EndShopPurchaseBlock(); ShopConfirmListPatches.ClearPendingQtyOpen(); GameCameras instance = GameCameras.instance; if (instance != null) { instance.HUDIn(); } MerchantStackerPlugin.Log.LogInfo((object)"Bulk buy done → popup + ResetShopWindow"); }); } internal static void ShowPurchaseFeedback(ShopItemStats? stats) { try { object obj; if (stats == null) { obj = null; } else { ShopItem item = stats.Item; obj = ((item != null) ? item.Item : null); } CollectableItem val = (CollectableItem)((obj is CollectableItem) ? obj : null); if (val != null) { CollectableUIMsg.Spawn((ICollectableUIMsgItem)(object)val, (CollectableUIMsg)null, false); CollectableItemHeroReaction.DoReaction(); } } catch (Exception ex) { MerchantStackerPlugin.Log.LogWarning((object)("ShowPurchaseFeedback: " + ex.Message)); } } private void Finish(bool confirmed) { if (!_active) { return; } int num = Math.Max(1, _quantity); bool hijacked = _hijacked; bool inShop = _inShop; Action originalYes = _originalYes; Action originalNo = _originalNo; Action<int> onConfirm = _onConfirm; Action onCancel = _onCancel; ShopItemStats shopStats = _shopStats; Action purchaseDone = _purchaseDone; Action shopCancel = _shopCancel; _active = false; _hijacked = false; _inShop = false; _shopRoot = null; _shopStats = null; _originalYes = null; _originalNo = null; _onConfirm = null; _onCancel = null; _purchaseDone = null; _shopCancel = null; _item = null; DestroyInShopHud(restoreTexts: true, !confirmed); ForceHideConfirmChromeOnly(shopStats); ClearPickerHudChildren(); ResetHoldState(); InventoryPaneInput.IsInputBlocked = false; ShopConfirmListPatches.ClearPendingQtyOpen(); if (confirmed) { PurchaseBatcher.PendingQuantity = num; MerchantStackerPlugin.Log.LogInfo((object)$"Qty confirmed: {num}"); } else { PurchaseBatcher.ClearPendingQuantity(); PurchaseBatcher.ExpectingFsmPurchase = false; PurchaseBatcher.EndShopPurchaseBlock(); } if (inShop) { if (confirmed && (Object)(object)shopStats != (Object)null) { CompleteInShopPurchase(shopStats, num, purchaseDone); return; } ScrubLeftoverQtyHud(); ClearPickerHudChildren(); ForceHideConfirmChromeOnly(shopStats); ShopSelectionCache.Clear(); ShopConfirmListPatches.BeginUiConfirmGrace(); shopCancel?.Invoke(); ScrubLeftoverQtyHud(); ClearPickerHudChildren(); MerchantStackerPlugin.Log.LogInfo((object)"Qty cancelled → ResetShopWindow"); } else if (hijacked) { object? value = InstanceField.GetValue(null); YesNoBox val = (YesNoBox)((value is YesNoBox) ? value : null); if ((Object)(object)val != (Object)null) { CurrentYesField.SetValue(val, originalYes); CurrentNoField.SetValue(val, originalNo); SelectedStateField.SetValue(val, confirmed); DoEndMethod.Invoke(val, null); } else if (confirmed) { originalYes?.Invoke(); } else { originalNo?.Invoke(); } } else { ClearBoxHandlersAndClose(); if (confirmed) { onConfirm?.Invoke(num); } else { onCancel?.Invoke(); } } } private static void ClearBoxHandlersAndClose() { object? value = InstanceField.GetValue(null); DialogueYesNoBox val = (DialogueYesNoBox)((value is DialogueYesNoBox) ? value : null); if ((Object)(object)val != (Object)null) { CurrentYesField.SetValue(val, null); CurrentNoField.SetValue(val, null); } try { DialogueYesNoBox.ForceClose(); } catch { } } private void ResetHoldState() { _upTimer = 0f; _downTimer = 0f; _upHeld = false; _downHeld = false; _upInterval = MerchantStackerPlugin.HoldInitialDelay.Value; _downInterval = MerchantStackerPlugin.HoldInitialDelay.Value; _heldStep = MerchantStackerPlugin.DpadStep.Value; } private void Update() { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Invalid comparison between Unknown and I4 //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Invalid comparison between Unknown and I4 ShopConfirmListPatches.PumpBlankConfirmWatchdog(); if (!_active) { return; } _maxRecalcTimer -= Time.unscaledDeltaTime; if (_maxRecalcTimer <= 0f) { _maxRecalcTimer = 0.25f; int affordableCount = Eligibility.GetAffordableCount(_unitCost, _currency); int val = (((Object)(object)_item != (Object)null) ? Eligibility.GetRoomUntilCap(_item) : _max); int num = Math.Max(1, Math.Min(Math.Max(1, affordableCount), Math.Max(1, val))); if (num != _max) { _max = num; if (_quantity > _max) { _quantity = _max; } if (_inShop) { _lastHudQty = int.MinValue; RefreshInShopHud(); } else { RefreshDisplay(); } } } InputHandler instance = ManagerSingleton<InputHandler>.Instance; if ((Object)(object)instance == (Object)null) { return; } HeroActions inputActions = instance.inputActions; MenuActions menuAction = Platform.Current.GetMenuAction(inputActions, false, false); if ((int)menuAction != 1) { if ((int)menuAction == 2) { Finish(confirmed: false); return; } int value = MerchantStackerPlugin.DpadStep.Value; int value2 = MerchantStackerPlugin.StickStep.Value; bool num2 = ((OneAxisInputControl)inputActions.Up).WasPressed || ((OneAxisInputControl)inputActions.RsUp).WasPressed; bool flag = ((OneAxisInputControl)inputActions.Down).WasPressed || ((OneAxisInputControl)inputActions.RsDown).WasPressed; bool upHeld = ((OneAxisInputControl)inputActions.Up).IsPressed || ((OneAxisInputControl)inputActions.RsUp).IsPressed; bool downHeld = ((OneAxisInputControl)inputActions.Down).IsPressed || ((OneAxisInputControl)inputActions.RsDown).IsPressed; int num3 = ((((OneAxisInputControl)inputActions.RsUp).WasPressed || ((OneAxisInputControl)inputActions.RsDown).WasPressed) ? value2 : value); int step = ((((OneAxisInputControl)inputActions.RsUp).IsPressed || ((OneAxisInputControl)inputActions.RsDown).IsPressed) ? value2 : value); if (num2) { Adjust(num3); BeginHold(up: true, step); } else if (flag) { Adjust(-num3); BeginHold(up: false, step); } else { TickHold(upHeld, downHeld, step); } } else { Finish(confirmed: true); } } private void BeginHold(bool up, int step) { _heldStep = step; float value = MerchantStackerPlugin.HoldInitialDelay.Value; if (up) { _upHeld = true; _downHeld = false; _upTimer = value; _upInterval = value; } else { _downHeld = true; _upHeld = false; _downTimer = value; _downInterval = value; } } private void TickHold(bool upHeld, bool downHeld, int step) { _heldStep = step; float value = MerchantStackerPlugin.HoldMinRepeat.Value; float value2 = MerchantStackerPlugin.HoldAccel.Value; float unscaledDeltaTime = Time.unscaledDeltaTime; if (upHeld && _upHeld) { _upTimer -= unscaledDeltaTime; if (_upTimer <= 0f) { Adjust(_heldStep); _upInterval = Math.Max(value, _upInterval * value2); _upTimer = _upInterval; } } else { _upHeld = false; _upInterval = MerchantStackerPlugin.HoldInitialDelay.Value; } if (downHeld && _downHeld) { _downTimer -= unscaledDeltaTime; if (_downTimer <= 0f) { Adjust(-_heldStep); _downInterval = Math.Max(value, _downInterval * value2); _downTimer = _downInterval; } } else { _downHeld = false; _downInterval = MerchantStackerPlugin.HoldInitialDelay.Value; } } private void Adjust(int delta) { int num = Math.Clamp(_quantity + delta, _min, _max); if (num != _quantity) { _quantity = num; PurchaseBatcher.PendingQuantity = _quantity; RefreshDisplay(); MerchantStackerPlugin.Log.LogInfo((object)$"Qty -> {_quantity}"); } } private void RefreshDisplay() { if (_inShop) { RefreshInShopHud(); } else { RefreshNativeDisplay(); } } private void RefreshNativeDisplay() { object? value = InstanceField.GetValue(null); DialogueYesNoBox val = (DialogueYesNoBox)((value is DialogueYesNoBox) ? value : null); if ((Object)(object)val == (Object)null) { return; } int num = _unitCost * _quantity; RequiredCurrencyAmountField.SetValue(val, num); object? value2 = CurrencyTextField.GetValue(val); TMP_Text val2 = (TMP_Text)((value2 is TMP_Text) ? value2 : null); if (val2 != null) { val2.text = num.ToString(CultureInfo.InvariantCulture); } if ((Object)(object)_item == (Object)null) { return; } WillGetItemField.SetValue(val, _item); EnsureWillGetDisplay(val, _item); if (!(InstantiatedItemsField.GetValue(val) is List<SavedItemDisplay> list)) { return; } foreach (SavedItemDisplay item in list) { if (!((Object)(object)item == (Object)null) && ((Component)item).gameObject.activeSelf) { item.Setup((SavedItem)(object)_item, _quantity); ForceAmountText(item, _quantity); break; } } } private static void EnsureWillGetDisplay(DialogueYesNoBox box, CollectableItem? item) { if ((Object)(object)item == (Object)null) { return; } try { if (!(InstantiatedItemsField.GetValue(box) is List<SavedItemDisplay> list)) { return; } object? value = ItemTemplateField.GetValue(box); SavedItemDisplay val = (SavedItemDisplay)((value is SavedItemDisplay) ? value : null); if (val != null) { while (list.Count < 1) { list.Add(Object.Instantiate<SavedItemDisplay>(val, ((Component)val).transform.parent)); } ((Component)list[0]).gameObject.SetActive(true); list[0].Setup((SavedItem)(object)item, 1); object? value2 = ItemsLayoutField.GetValue(box); Behaviour val2 = (Behaviour)((value2 is Behaviour) ? value2 : null); if (val2 != null) { ((Component)val2).gameObject.SetActive(true); } } } catch { } } private static void ForceAmountText(SavedItemDisplay display, int qty) { try { object? obj = AccessTools.Field(typeof(SavedItemDisplay), "amountText")?.GetValue(display); TMP_Text val = (TMP_Text)((obj is TMP_Text) ? obj : null); if (val != null) { ((Component)val).gameObject.SetActive(true); val.text = qty.ToString(CultureInfo.InvariantCulture); } } catch { } } } internal static class ShopSelectionCache { private static readonly string[] ItemObjectVarNames = new string[3] { "Shop Item", "Item", "Selected Item" }; private static readonly string[] ItemIndexVarNames = new string[3] { "Current Item", "Item Number", "Selected Index" }; internal static ShopItemStats? Stats { get; private set; } internal static ShopItem? Item { get { if (!((Object)(object)Stats != (Object)null)) { return null; } return Stats.Item; } } internal static void Remember(ShopItemStats? stats) { if (!((Object)(object)stats == (Object)null) && !((Object)(object)stats.Item == (Object)null)) { Stats = stats; } } internal static void Clear() { Stats = null; } internal static ShopItemStats? ResolveStats() { ShopItemStats? stats = Stats; if ((Object)(object)((stats != null) ? stats.Item : null) != (Object)null) { return Stats; } if (TryResolveFromFsm(out ShopItemStats stats2)) { Remember(stats2); return stats2; } InventoryItemManager[] array = Object.FindObjectsByType<InventoryItemManager>((FindObjectsSortMode)0); foreach (InventoryItemManager val in array) { if (!((Object)(object)((val != null) ? val.CurrentSelected : null) == (Object)null)) { ShopItemStats statsFromGameObject = GetStatsFromGameObject(((Component)val.CurrentSelected).gameObject); if ((Object)(object)((statsFromGameObject != null) ? statsFromGameObject.Item : null) != (Object)null) { Remember(statsFromGameObject); return statsFromGameObject; } } } return null; } private static bool TryResolveFromFsm(out ShopItemStats? stats) { stats = null; PlayMakerFSM[] array = Object.FindObjectsByType<PlayMakerFSM>((FindObjectsSortMode)0); foreach (PlayMakerFSM val in array) { if ((Object)(object)val == (Object)null || !((Behaviour)val).isActiveAndEnabled || val.FsmVariables == null) { continue; } string[] itemObjectVarNames = ItemObjectVarNames; foreach (string text in itemObjectVarNames) { FsmGameObject val2 = val.FsmVariables.FindFsmGameObject(text); if (!((Object)(object)((val2 != null) ? val2.Value : null) == (Object)null)) { stats = GetStatsFromGameObject(val2.Value); ShopItemStats? obj = stats; if ((Object)(object)((obj != null) ? obj.Item : null) != (Object)null) { MerchantStackerPlugin.Log.LogDebug((object)("Shop item from FSM '" + text + "': " + stats.Item.DisplayName)); return true; } } } itemObjectVarNames = ItemIndexVarNames; foreach (string text2 in itemObjectVarNames) { FsmInt val3 = val.FsmVariables.FindFsmInt(text2); if (val3 == null) { continue; } ShopMenuStock val4 = ((Component)val).GetComponent<ShopMenuStock>() ?? ((Component)val).GetComponentInParent<ShopMenuStock>() ?? ((Component)val).GetComponentInChildren<ShopMenuStock>(true); if ((Object)(object)val4 == (Object)null) { continue; } int value = val3.Value; if (value >= 0 && value < val4.GetItemCount()) { stats = GetStatsFromGameObject(val4.GetItemGameObject(value)); ShopItemStats? obj2 = stats; if ((Object)(object)((obj2 != null) ? obj2.Item : null) != (Object)null) { MerchantStackerPlugin.Log.LogDebug((object)$"Shop item from FSM '{text2}'={value}: {stats.Item.DisplayName}"); return true; } } } } stats = null; return false; } internal static ShopItemStats? GetStatsFromGameObject(GameObject? go) { if ((Object)(object)go == (Object)null) { return null; } return go.GetComponent<ShopItemStats>() ?? go.GetComponentInChildren<ShopItemStats>(true) ?? go.GetComponentInParent<ShopItemStats>(); } } [HarmonyPatch] internal static class ShopSelectionCachePatches { [HarmonyPostfix] [HarmonyPatch(typeof(InventoryItemSelectable), "Select")] private static void SelectPostfix(InventoryItemSelectable __instance) { ShopSelectionCache.Remember(ShopSelectionCache.GetStatsFromGameObject((__instance != null) ? ((Component)__instance).gameObject : null)); } [HarmonyPostfix] [HarmonyPatch(typeof(InventoryItemManager), "SetSelected", new Type[] { typeof(GameObject), typeof(bool) })] private static void SetSelectedGoPostfix(GameObject selectedGameObject) { ShopSelectionCache.Remember(ShopSelectionCache.GetStatsFromGameObject(selectedGameObject)); } [HarmonyPostfix] [HarmonyPatch(typeof(InventoryItemManager), "SetSelected", new Type[] { typeof(InventoryItemSelectable), typeof(SelectionDirection?), typeof(bool) })] private static void SetSelectedSelectablePostfix(InventoryItemSelectable selectable) { ShopSelectionCache.Remember(ShopSelectionCache.GetStatsFromGameObject((selectable != null) ? ((Component)selectable).gameObject : null)); } [HarmonyPrefix] [HarmonyPatch(typeof(SetShopItemPurchased), "OnEnter")] private static void CachePurchaseTargetV1(SetShopItemPurchased __instance) { ShopSelectionCache.Remember(ShopSelectionCache.GetStatsFromGameObject(FSMUtility.GetSafe(__instance.Target, (FsmStateAction)(object)__instance))); } [HarmonyPrefix] [HarmonyPatch(typeof(SetShopItemPurchasedV2), "OnEnter")] private static void CachePurchaseTargetV2(SetShopItemPurchasedV2 __instance) { ShopSelectionCache.Remember(ShopSelectionCache.GetStatsFromGameObject(FSMUtility.GetSafe(__instance.Target, (FsmStateAction)(object)__instance))); } [HarmonyPostfix] [HarmonyPatch(typeof(ShopMenuStock), "GetItemGameObject")] private static void GetItemGameObjectPostfix(ShopMenuStock __instance, int itemNum, GameObject __result) { ShopSelectionCache.Remember(ShopSelectionCache.GetStatsFromGameObject(__result)); } [HarmonyPostfix] [HarmonyPatch(typeof(ShopMenuStock), "GetCost")] private static void GetCostPostfix(ShopMenuStock __instance, int itemNum) { try { ShopSelectionCache.Remember(ShopSelectionCache.GetStatsFromGameObject(__instance.GetItemGameObject(itemNum))); } catch { } } } } namespace MerchantStacker.Patches { [HarmonyPatch] internal static class ConfirmDialogPatches { private static readonly FieldInfo CurrentYesField = AccessTools.Field(typeof(YesNoBox), "currentYes"); private static readonly FieldInfo CurrentNoField = AccessTools.Field(typeof(YesNoBox), "currentNo"); private static readonly FieldInfo RequiredCurrencyAmountField = AccessTools.Field(typeof(DialogueYesNoBox), "requiredCurrencyAmount"); private static readonly FieldInfo WillGetItemField = AccessTools.Field(typeof(DialogueYesNoBox), "willGetItem"); [HarmonyPostfix] [HarmonyPatch(typeof(YesNoBox), "InternalOpen")] private static void InternalOpenPostfix(YesNoBox __instance) { //IL_0117: Unknown result type (might be due to invalid IL or missing references) try { if (!MerchantStackerPlugin.Enabled.Value || PurchaseBatcher.IsBatching || QuantityPicker.SuppressHijack || (Object)(object)QuantityPicker.Instance == (Object)null || QuantityPicker.Instance.IsOpen) { return; } DialogueYesNoBox val = (DialogueYesNoBox)(object)((__instance is DialogueYesNoBox) ? __instance : null); if (val == null || IsMerchantShopOpen()) { return; } int valueOrDefault = (RequiredCurrencyAmountField?.GetValue(val) as int?).GetValueOrDefault(); if (valueOrDefault <= 0) { return; } ShopItemStats val2 = ShopSelectionCache.ResolveStats(); if (!((Object)(object)((val2 != null) ? val2.Item : null) == (Object)null) && Eligibility.ShouldOfferBulkQty(val2.Item)) { object? obj = WillGetItemField?.GetValue(val); CollectableItem val3 = (CollectableItem)(((obj is CollectableItem) ? obj : null) ?? ((object)/*isinst with value type is only supported in some contexts*/)); if (!((Object)(object)val3 == (Object)null)) { QuantityPicker.Instance.Hijack(val, val2.Item.DisplayName, val3, (val2.Item.Cost > 0) ? val2.Item.Cost : valueOrDefault, val2.Item.CurrencyType, Eligibility.GetMaxQuantity(val2.Item), CurrentYesField?.GetValue(val) as Action, CurrentNoField?.GetValue(val) as Action); } } } catch (Exception arg) { MerchantStackerPlugin.Log.LogError((object)$"ConfirmDialogPatches: {arg}"); } } private static bool IsMerchantShopOpen() { try { ShopMenuStock[] array = Object.FindObjectsByType<ShopMenuStock>((FindObjectsSortMode)0); foreach (ShopMenuStock val in array) { if ((Object)(object)val != (Object)null && ((Behaviour)val).isActiveAndEnabled) { return true; } } } catch { } return false; } } [HarmonyPatch(typeof(InventoryPaneInput), "Update")] internal static class InventoryPaneInputPatches { [HarmonyPrefix] private static bool Prefix() { if (!((Object)(object)QuantityPicker.Instance == (Object)null)) { return !QuantityPicker.Instance.IsOpen; } return true; } } [HarmonyPatch] internal static class MachinePurchasePatches { private static int _pendingCollectQty; private static bool _skipNextCollect; private static bool _waitingForConfirm; private static CollectableItem? _pendingItem; private static TakeCurrency? _heldTakeAction; private static int _heldUnitCost; private static CurrencyType _heldCurrency; [HarmonyPrefix] [HarmonyPatch(typeof(TakeCurrency), "OnEnter")] private static bool TakeCurrencyPrefix(TakeCurrency __instance) { //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005b: 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_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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_0133: Unknown result type (might be due to invalid IL or missing references) if (!MerchantStackerPlugin.Enabled.Value || PurchaseBatcher.IsBatching || _waitingForConfirm) { return true; } if (((NamedVariable)__instance.CurrencyType).IsNone || __instance.Amount.Value <= 0) { return true; } int num = PurchaseBatcher.ConsumePendingQuantity(); if (num > 1 && IsRosaryStringMachine((FsmStateAction)(object)__instance)) { CurrencyType val = (CurrencyType)(object)__instance.CurrencyType.Value; CurrencyManager.TakeCurrency(__instance.Amount.Value * num, val, true); _pendingCollectQty = num; _skipNextCollect = false; ((FsmStateAction)__instance).Finish(); return false; } if (num == 1) { return true; } if (!IsRosaryStringMachine((FsmStateAction)(object)__instance)) { return true; } CurrencyType val2 = (CurrencyType)(object)__instance.CurrencyType.Value; int value = __instance.Amount.Value; CollectableItem val3 = FindMachineCollectable((FsmStateAction)(object)__instance); int val4 = (((Object)(object)val3 != (Object)null) ? Eligibility.GetRoomUntilCap(val3) : 20); int affordableCount = Eligibility.GetAffordableCount(value, val2); int num2 = Math.Max(1, Math.Min(val4, affordableCount)); if (num2 <= 1 || (Object)(object)val3 == (Object)null) { return true; } if ((Object)(object)QuantityPicker.Instance == (Object)null) { return true; } _waitingForConfirm = true; _heldTakeAction = __instance; _heldUnitCost = value; _heldCurrency = val2; _pendingItem = val3; QuantityPicker.Instance.Open(((SavedItem)val3).GetPopupName(), val3, value, val2, num2, delegate(int qty) { //IL_001d: Unknown result ty