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 TradersExtended v1.3.12
TradersExtended.dll
Decompiled 7 months 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.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using AzuExtendedPlayerInventory; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExtraSlots; using GUIFramework; using HarmonyLib; using JetBrains.Annotations; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using ServerSync; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("Traders Extended")] [assembly: AssemblyDescription("")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyProduct("Traders Extended")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("6d6f243e-c80e-4a33-b2d0-a2657d3b9f7f")] [assembly: AssemblyFileVersion("1.3.12")] [assembly: AssemblyCompany("")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.3.12.0")] [module: UnverifiableCode] namespace TradersExtended { internal static class AmountDialog { [HarmonyPatch(typeof(StoreGui), "OnSelectedItem")] public static class StoreGui_OnSelectedItem_SelectItem { private static void Postfix() { if (TradersExtended.modEnabled.Value) { OnSelectedTradeableItemClick(sellDialog: false); } } } private static float clickTime; private static GameObject amountDialog; private static Slider sliderDialog; private static TMP_Text sliderTitle; private static TMP_Text sliderAmountText; private static TMP_Text sliderAmountCoinsText; private static TMP_Text sliderButtonOk; private static Image sliderImage; private static string sliderTitleText; private static string sliderButtonText; private static StoreGui storeGui; private const float m_splitNumInputTimeoutSec = 0.5f; private static string m_splitInput = ""; private static DateTime m_lastSplitInput; private static bool isSellDialog; public static GameObject Init(StoreGui store) { //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0168: 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_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_022b: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027d: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02f3: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_035c: Unknown result type (might be due to invalid IL or missing references) //IL_0366: Expected O, but got Unknown //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Expected O, but got Unknown storeGui = store; amountDialog = Object.Instantiate<GameObject>(((Component)InventoryGui.instance.m_splitPanel).gameObject, storeGui.m_rootPanel.transform.parent); ((Object)amountDialog).name = "AmountDialog"; Transform val = amountDialog.transform.Find("win_bkg"); sliderTitle = ((Component)val.Find("Text")).GetComponent<TMP_Text>(); sliderDialog = ((Component)val.Find("Slider")).GetComponent<Slider>(); sliderAmountText = ((Component)val.Find("amount")).GetComponent<TMP_Text>(); sliderImage = ((Component)val.Find("Icon_bkg/Icon")).GetComponent<Image>(); sliderButtonOk = ((Component)val.Find("Button_ok/Text")).GetComponent<TMP_Text>(); Transform val2 = val.Find("Icon_bkg"); GameObject val3 = Object.Instantiate<GameObject>(((Component)val2).gameObject, val); ((Object)val3).name = "Coins_bkg"; val3.transform.SetSiblingIndex(val2.GetSiblingIndex() + 1); Image component = ((Component)val3.transform.Find("Icon")).GetComponent<Image>(); component.sprite = storeGui.m_coinPrefab.m_itemData.GetIcon(); RectTransform component2 = val3.GetComponent<RectTransform>(); component2.anchorMax += new Vector2(0.15f, 0f); component2.anchorMin += new Vector2(0.15f, 0f); RectTransform component3 = ((Component)val2).GetComponent<RectTransform>(); component3.anchorMax -= new Vector2(0.15f, 0f); component3.anchorMin -= new Vector2(0.15f, 0f); GameObject val4 = Object.Instantiate<GameObject>(((Component)sliderAmountText).gameObject, val); ((Object)val4).name = "amount_coins"; val4.transform.SetSiblingIndex(sliderAmountText.transform.GetSiblingIndex() + 1); sliderAmountCoinsText = val4.GetComponent<TMP_Text>(); RectTransform component4 = ((Component)sliderAmountText).GetComponent<RectTransform>(); component4.anchorMax -= new Vector2(0.15f, 0f); component4.anchorMin -= new Vector2(0.15f, 0f); RectTransform component5 = val4.GetComponent<RectTransform>(); component5.anchorMax += new Vector2(0.15f, 0f); component5.anchorMin += new Vector2(0.15f, 0f); GameObject val5 = Object.Instantiate<GameObject>(((Component)sliderTitle).gameObject, val); ((Object)val5).name = "equal"; val5.transform.SetSiblingIndex(sliderTitle.transform.GetSiblingIndex() + 1); RectTransform component6 = val5.GetComponent<RectTransform>(); component6.anchorMin -= new Vector2(0f, 0.5f); val5.GetComponent<TMP_Text>().SetText("="); ((UnityEvent<float>)(object)sliderDialog.onValueChanged).AddListener((UnityAction<float>)OnSplitSliderChanged); ((UnityEvent)((Component)val.Find("Button_ok")).GetComponent<Button>().onClick).AddListener(new UnityAction(OnOkClick)); ((UnityEvent)((Component)val.Find("Button_cancel")).GetComponent<Button>().onClick).AddListener(new UnityAction(Close)); return amountDialog; } public static void OnOkClick() { BuySelectedItem(); } public static void SetSellState(bool sellDialog) { isSellDialog = sellDialog; } public static void OnSelectedTradeableItemClick(bool sellDialog) { SetSellState(sellDialog); if (Time.time - clickTime < 0.3f) { Open(); clickTime = 0f; } else { clickTime = Time.time; } } public static bool IsOpen() { return (Object)(object)amountDialog != (Object)null && amountDialog.activeInHierarchy; } public static void Update() { if ((Object)(object)amountDialog == (Object)null) { return; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead() || ((Character)localPlayer).InCutscene() || ((Character)localPlayer).IsTeleporting()) { Close(); } else { if ((Object)(object)sliderDialog == (Object)null || !((Component)sliderDialog).gameObject.activeInHierarchy) { return; } sliderTitle.SetText(sliderTitleText); sliderButtonOk.SetText(sliderButtonText); for (int i = 0; i < 10; i++) { if (ZInput.GetKeyDown((KeyCode)(256 + i), true) || ZInput.GetKeyDown((KeyCode)(48 + i), true)) { if (m_lastSplitInput + TimeSpan.FromSeconds(0.5) < DateTime.Now) { m_splitInput = ""; } m_lastSplitInput = DateTime.Now; m_splitInput += i; if (int.TryParse(m_splitInput, out var result)) { sliderDialog.value = Mathf.Clamp((float)result, 1f, sliderDialog.maxValue); OnSplitSliderChanged(); } } } if (ZInput.GetKeyDown((KeyCode)276, true) && sliderDialog.value > 1f) { Slider obj = sliderDialog; obj.value -= 1f; OnSplitSliderChanged(); } if (ZInput.GetKeyDown((KeyCode)275, true) && sliderDialog.value < sliderDialog.maxValue) { Slider obj2 = sliderDialog; obj2.value += 1f; OnSplitSliderChanged(); } if (ZInput.GetButtonDown("JoyLTrigger") && sliderDialog.value > 10f) { Slider obj3 = sliderDialog; obj3.value -= 10f; OnSplitSliderChanged(); } if (ZInput.GetButtonDown("JoyRTrigger") && sliderDialog.value < sliderDialog.maxValue) { Slider obj4 = sliderDialog; obj4.value += 10f; OnSplitSliderChanged(); } if (ZInput.GetButtonDown("JoyLBumper") && sliderDialog.value > 5f) { Slider obj5 = sliderDialog; obj5.value -= 5f; OnSplitSliderChanged(); } if (ZInput.GetButtonDown("JoyRBumper") && sliderDialog.value < sliderDialog.maxValue) { Slider obj6 = sliderDialog; obj6.value += 5f; OnSplitSliderChanged(); } if (ZInput.GetKeyDown((KeyCode)271, true) || ZInput.GetKeyDown((KeyCode)13, true)) { BuySelectedItem(); } if (((Object)(object)Chat.instance == (Object)null || !Chat.instance.HasFocus()) && !Console.IsVisible() && !Menu.IsVisible() && Object.op_Implicit((Object)(object)TextViewer.instance) && !TextViewer.instance.IsVisible() && !((Character)localPlayer).InCutscene() && (ZInput.GetButtonDown("JoyButtonB") || ZInput.GetKeyDown((KeyCode)27, true))) { ZInput.ResetButtonStatus("JoyButtonB"); Close(); } } } public static void Close() { GameObject obj = amountDialog; if (obj != null) { obj.SetActive(false); } } public static void Open() { if ((Object)(object)amountDialog == (Object)null) { return; } TradersExtended.LogInfo(isSellDialog); if (isSellDialog) { StorePanel.ItemToSell selectedItem = StorePanel.selectedItem; if (selectedItem == null || selectedItem.itemType != StorePanel.ItemToSell.ItemType.Combined || selectedItem.pricePerItem == 0 || !((Humanoid)Player.m_localPlayer).GetInventory().HaveItem(selectedItem.item.m_shared.m_name, true)) { return; } int num = selectedItem.amount; if (TradersExtended.traderUseCoins.Value) { int traderCoins = TraderCoins.GetTraderCoins(); if (traderCoins < selectedItem.pricePerItem) { return; } num = Mathf.Min(traderCoins / selectedItem.pricePerItem, num); } SetDialogAndOpen(selectedItem.item, num); } else { if (!((Humanoid)Player.m_localPlayer).GetInventory().HaveEmptySlot()) { return; } TradeItem selectedItem2 = storeGui.m_selectedItem; if (selectedItem2 != null && !StorePanel.ItemToSell.IsBuyBackItem(selectedItem2)) { int playerCoins = storeGui.GetPlayerCoins(); if (TradersExtended.TradeableItem.GetStackFromStack(selectedItem2.m_stack) == 1 && selectedItem2.m_prefab.m_itemData.m_shared.m_maxStackSize != 1 && playerCoins >= selectedItem2.m_price) { SetDialogAndOpen(selectedItem2.m_prefab.m_itemData, Mathf.CeilToInt((float)(playerCoins / selectedItem2.m_price))); } } } } private static void SetDialogAndOpen(ItemData item, int maxValue) { sliderTitleText = Localization.instance.Localize(item.m_shared.m_name); sliderButtonText = Localization.instance.Localize(isSellDialog ? "$store_sell" : "$store_buy"); sliderDialog.value = 1f; sliderDialog.minValue = 1f; sliderDialog.maxValue = Math.Min(item.m_shared.m_maxStackSize, maxValue); sliderImage.sprite = item.GetIcon(); OnSplitSliderChanged(); amountDialog.SetActive(true); } public static void OnSplitSliderChanged(float value = 0f) { sliderAmountText.SetText(((int)sliderDialog.value).ToString()); sliderAmountCoinsText.SetText(GetPrice().ToString()); } private static void BuySelectedItem() { if (isSellDialog) { if (TraderCanAffordSelectedItem()) { StorePanel.selectedItem.amount = Mathf.CeilToInt(sliderDialog.value); StorePanel.selectedItem.price = GetPrice(); StorePanel.SellSelectedItem(storeGui); } } else if (CanAffordSelectedItem()) { TradersExtended.TradeableItem.GetStackQualityFromStack(storeGui.m_selectedItem.m_stack, out var stack, out var quality); stack = Mathf.Min(Mathf.CeilToInt(sliderDialog.value), storeGui.m_selectedItem.m_prefab.m_itemData.m_shared.m_maxStackSize); storeGui.m_selectedItem.m_stack = TradersExtended.TradeableItem.GetStackFromStackQuality(stack, quality); TradeItem selectedItem = storeGui.m_selectedItem; selectedItem.m_price *= stack; storeGui.BuySelectedItem(); } Close(); } private static bool TraderCanAffordSelectedItem() { if (StorePanel.selectedItem == null) { return false; } return TraderCoins.CanSell(GetPrice()); } private static bool CanAffordSelectedItem() { if (storeGui.m_selectedItem == null) { return false; } int playerCoins = storeGui.GetPlayerCoins(); return GetPrice() <= playerCoins && ((Humanoid)Player.m_localPlayer).GetInventory().HaveEmptySlot(); } private static int GetPricePerItem() { return isSellDialog ? StorePanel.selectedItem.pricePerItem : storeGui.m_selectedItem.m_price; } internal static int GetPrice() { return Mathf.CeilToInt((float)((int)sliderDialog.value * GetPricePerItem()) * (isSellDialog ? TraderCoins.GetPriceFactor(buyPrice: false) : 1f)); } } internal static class CoinsPatches { [HarmonyPatch(typeof(ObjectDB), "Awake")] public static class ObjectDB_Awake_CoinsPatch { [HarmonyPriority(0)] private static void Postfix() { UpdateCoinsPrefab(); } } [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] public static class ObjectDB_CopyOtherDB_CoinsPatch { [HarmonyPriority(0)] private static void Postfix() { UpdateCoinsPrefab(); } } [HarmonyPatch(typeof(Player), "AddKnownItem")] public static class Player_AddKnownItem_CoinsPatch { private static void Postfix(ref ItemData item) { if (!(item.m_shared.m_name != "$item_coins")) { PatchCoinsItemData(item); } } } [HarmonyPatch(typeof(Player), "OnSpawned")] public class Player_OnSpawned_CoinsPatch { public static void Postfix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { PatchCoinsInInventory(((Humanoid)__instance).GetInventory()); } } } [HarmonyPatch(typeof(Inventory), "Load")] public class Inventory_Load_CoinsPatch { public static void Postfix(Inventory __instance) { PatchCoinsInInventory(__instance); } } [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData), typeof(int), typeof(int), typeof(int) })] private static class Inventory_AddItem_ItemData_amount_x_y_PatchCircletItemDataOnLoad { [HarmonyPriority(800)] private static void Prefix(ItemData item) { if (!(item.m_shared.m_name != "$item_coins")) { PatchCoinsItemData(item); } } } [HarmonyPatch(typeof(ItemDrop), "Start")] public static class ItemDrop_Start_CoinsPatch { private static void Postfix(ItemDrop __instance) { if (!(__instance.GetPrefabName(((Object)__instance).name) != "Coins")) { PatchCoinsItemData(__instance.m_itemData); } } } public const string itemNameCoins = "Coins"; public const string itemDropNameCoins = "$item_coins"; private static List<ItemData> _itemDataList = new List<ItemData>(); public static void PatchCoinsItemData(ItemData coins) { if (TradersExtended.modEnabled.Value && coins != null && TradersExtended.coinsPatch.Value) { coins.m_shared.m_weight = TradersExtended.coinsWeight.Value; coins.m_shared.m_maxStackSize = TradersExtended.coinsStackSize.Value; } } public static void PatchCoinsInInventory(Inventory inventory) { if (inventory == null) { return; } _itemDataList.Clear(); inventory.GetAllItems("$item_coins", _itemDataList); foreach (ItemData itemData in _itemDataList) { PatchCoinsItemData(itemData); } } public static void UpdateCoinsPrefab() { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab("Coins"); if ((Object)(object)itemPrefab != (Object)null) { PatchCoinsItemData(itemPrefab.GetComponent<ItemDrop>()?.m_itemData); } Player localPlayer = Player.m_localPlayer; PatchCoinsInInventory((localPlayer != null) ? ((Humanoid)localPlayer).GetInventory() : null); } } internal static class StorePanel { public class ItemToSell { public enum ItemType { Single, Stack, Combined } private const string c_buybackItem = "buybackItem"; public ItemType itemType = ItemType.Single; public ItemData item; public int stack; public int price; public int amount; public int quality; public int pricePerItem; public ItemToSell Clone() { ItemToSell itemToSell = MemberwiseClone() as ItemToSell; itemToSell.item = item.Clone(); return itemToSell; } public static bool IsBuyBackItem(TradeItem item) { return item?.m_requiredGlobalKey == "buybackItem"; } public static TradeItem SetBuyBackItem(TradeItem item) { item.m_requiredGlobalKey = "buybackItem"; return item; } } [HarmonyPatch(typeof(StoreGui), "Awake")] public static class StoreGui_Awake_InitializePanel { private static GuiInputField InitFilterField(Transform parent) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) GameObject val = Object.Instantiate<GameObject>(((Component)TextInput.instance.m_inputField).gameObject, parent); ((Object)val).name = "FilterField"; val.transform.localPosition = new Vector3(125f, -51f, 0f); val.transform.SetSiblingIndex(val.transform.parent.Find("topic").GetSiblingIndex() + 1); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(1f, 0.5f); component.anchorMax = new Vector2(0f, 0.5f); component.sizeDelta -= new Vector2(0f, 10f); GuiInputField component2 = val.GetComponent<GuiInputField>(); component2.VirtualKeyboardTitle = "$menu_filter"; ((Component)((Component)component2).transform.Find("Text Area/Placeholder")).GetComponent<TMP_Text>().SetText(Localization.instance.Localize("$menu_filter")); return component2; } [HarmonyPriority(800)] private static void Postfix(StoreGui __instance) { //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_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_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01f9: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_036a: Unknown result type (might be due to invalid IL or missing references) //IL_0388: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Unknown result type (might be due to invalid IL or missing references) //IL_03a1: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Expected O, but got Unknown //IL_0463: Unknown result type (might be due to invalid IL or missing references) //IL_0468: Unknown result type (might be due to invalid IL or missing references) //IL_04ad: Unknown result type (might be due to invalid IL or missing references) //IL_0506: Unknown result type (might be due to invalid IL or missing references) //IL_05d1: Unknown result type (might be due to invalid IL or missing references) //IL_05e0: Unknown result type (might be due to invalid IL or missing references) //IL_05e5: Unknown result type (might be due to invalid IL or missing references) if (!TradersExtended.modEnabled.Value) { return; } TradersExtended.FillConfigLists(); sellPanel = Object.Instantiate<GameObject>(__instance.m_rootPanel, __instance.m_rootPanel.transform); sellPanel.transform.localPosition = new Vector3(250f, 0f, 0f); ((Object)sellPanel).name = "StoreSell"; sellPanel.SetActive(true); RectTransform component = __instance.m_rootPanel.GetComponent<RectTransform>(); component.sizeDelta += new Vector2(0f, 35f); RectTransform component2 = __instance.m_listElement.GetComponent<RectTransform>(); ((Transform)component2).localPosition = ((Transform)component2).localPosition - new Vector3(0f, 35f, 0f); Object.Destroy((Object)(object)((Component)sellPanel.transform.Find("SellPanel")).gameObject); Object.Destroy((Object)(object)((Component)sellPanel.transform.Find("border (1)")).gameObject); Object.Destroy((Object)(object)((Component)sellPanel.transform.Find("bkg")).gameObject); Transform obj = __instance.m_rootPanel.transform.Find("ItemList"); obj.localPosition -= new Vector3(0f, 35f, 0f); Transform obj2 = sellPanel.transform.Find("ItemList"); obj2.localPosition -= new Vector3(0f, 35f, 0f); RectTransform component3 = ((Component)sellPanel.transform.Find("coins")).GetComponent<RectTransform>(); ((Transform)component3).localPosition = ((Transform)component3).localPosition - new Vector3(0f, 35f, 0f); Transform val = sellPanel.transform.Find("ItemList/Items"); listRoot = ((Component)val.Find("ListRoot")).GetComponent<RectTransform>(); listElement = ((Component)val.Find("ItemElement")).gameObject; itemEnsureVisible = ((Component)val).GetComponent<ScrollRectEnsureVisible>(); StorePanel.tooltipAnchor = ((Component)sellPanel.transform.Find("TooltipAnchor")).GetComponent<RectTransform>(); storeName = ((Component)__instance.m_rootPanel.transform.Find("topic")).GetComponent<TMP_Text>(); playerName = ((Component)sellPanel.transform.Find("topic")).GetComponent<TMP_Text>(); TraderCoins.playerCoins = ((Component)sellPanel.transform.Find("coins/coins")).GetComponent<TMP_Text>(); TraderCoins.traderCoins = __instance.m_coinText; TraderCoins.traderCoinsPanel = ((Component)__instance.m_rootPanel.transform.Find("coins")).gameObject; Transform val2 = sellPanel.transform.Find("BuyButton"); ((Component)val2.Find("Text")).GetComponent<TMP_Text>().SetText(Localization.instance.Localize("$store_sell")); ((Component)val2).GetComponent<UIGamePad>().m_zinputKey = "JoyButtonX"; val2.localPosition -= new Vector3(0f, 35f, 0f); GameObject val3 = RepairPanel.RepurposeSellButton(__instance); Transform transform = val3.transform; transform.localPosition -= new Vector3(0f, 35f, 0f); sellButton = ((Component)val2).GetComponent<Button>(); ((UnityEventBase)sellButton.onClick).SetPersistentListenerState(0, (UnityEventCallState)0); ((UnityEvent)sellButton.onClick).AddListener((UnityAction)delegate { __instance.OnSellItem(); }); traderFilter = InitFilterField(__instance.m_rootPanel.transform); ((UnityEvent<string>)(object)((TMP_InputField)traderFilter).onValueChanged).AddListener((UnityAction<string>)delegate { __instance.FillList(); }); playerFilter = InitFilterField(sellPanel.transform); ((UnityEvent<string>)(object)((TMP_InputField)playerFilter).onValueChanged).AddListener((UnityAction<string>)delegate { FillSellableList(__instance); }); UIGamePad component4 = ((Component)sellButton).GetComponent<UIGamePad>(); Vector3 localPosition = component4.m_hint.transform.localPosition; Object.Destroy((Object)(object)component4.m_hint); component4.m_hint = Object.Instantiate<GameObject>(((Component)InventoryGui.instance.m_craftButton).GetComponent<UIGamePad>().m_hint, ((Component)sellButton).transform); component4.m_hint.transform.localPosition = localPosition; ((Object)component4.m_hint).name = ((Object)component4.m_hint).name.Replace("(clone)", ""); ((Component)__instance.m_rootPanel.transform.Find("border (1)")).GetComponent<RectTransform>().anchorMax = new Vector2(2f, 1f); GameObject val4 = AmountDialog.Init(__instance); ((Component)__instance.m_rootPanel.transform.Find("BuyButton")).GetComponent<UIGamePad>().m_blockingElements.Add(val4); ((Component)sellButton).GetComponent<UIGamePad>().m_blockingElements.Add(val4); RepairPanel.AddButtonBlocker(val4); if ((Object)(object)TradersExtended.epicLootPlugin != (Object)null) { MethodInfo IsAdventureModeEnabledMethod = AccessTools.Method(((object)TradersExtended.epicLootPlugin).GetType(), "IsAdventureModeEnabled", (Type[])null, (Type[])null); if (IsAdventureModeEnabledMethod != null) { _adventureModeEnabled = () => (bool)IsAdventureModeEnabledMethod.Invoke(null, null); } } RectTransform tooltipAnchor = __instance.m_tooltipAnchor; tooltipAnchor.anchorMax += new Vector2(1f, 0f); TradersExtended.LogInfo("StoreGui panel patched"); TradersExtended.SetupConfigWatcher(); buybackItem = null; } } [HarmonyPatch(typeof(Trader), "GetAvailableItems")] public static class Trader_GetAvailableItems_FillBuyableItems { [HarmonyAfter(new string[] { "org.bepinex.plugins.travelinghaldor" })] [HarmonyPriority(800)] private static void Postfix(Trader __instance, List<TradeItem> __result) { if (TradersExtended.modEnabled.Value) { if (TradersExtended.disableVanillaItems.Value) { __result.Clear(); } AddAvailableItems(TradersExtended.CommonListKey(TradersExtended.ItemsListType.Buy), __result); AddAvailableItems(TradersExtended.TraderListKey(__instance, TradersExtended.ItemsListType.Buy), __result); } } } [HarmonyPatch(typeof(Trader), "GetAvailableItems")] public static class Trader_GetAvailableItems_FilterAndFlexiblePrices { public static bool ItemIsValid(ItemDrop item) { try { object obj; if (item == null) { obj = null; } else { ItemData itemData = item.m_itemData; obj = ((itemData != null) ? itemData.GetIcon() : null); } return (Object)obj != (Object)null; } catch { return false; } } [HarmonyPriority(0)] public static void Postfix(List<TradeItem> __result) { //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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_0158: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown if (!TradersExtended.modEnabled.Value) { return; } float priceFactor = TraderCoins.GetPriceFactor(buyPrice: true); for (int num = __result.Count - 1; num >= 0; num--) { if (!ItemIsValid(__result[num].m_prefab)) { __result.RemoveAt(num); } else if (!string.IsNullOrWhiteSpace(((TMP_InputField)traderFilter).text) && Localization.instance.Localize(__result[num].m_prefab.m_itemData.m_shared.m_name).ToLower().IndexOf(((TMP_InputField)traderFilter).text.ToLower()) == -1) { __result.RemoveAt(num); } else { __result[num] = JsonUtility.FromJson<TradeItem>(JsonUtility.ToJson((object)__result[num])); if (TradersExtended.traderUseFlexiblePricing.Value) { __result[num].m_price = Math.Max((int)((float)__result[num].m_price * priceFactor), 1); TradersExtended.TradeableItem.NormalizeStack(__result[num]); } } } if (TradersExtended.enableBuyBack.Value && buybackItem != null) { __result.Insert(0, ItemToSell.SetBuyBackItem(new TradeItem { m_prefab = null, m_stack = 0, m_price = buybackItem.price })); } } } [HarmonyPatch(typeof(StoreGui), "UpdateSellButton")] public static class StoreGui_UpdateSellButton_Patch { private static void Postfix(StoreGui __instance) { if (TradersExtended.modEnabled.Value) { UpdateSellButton(); RepairPanel.Update(__instance); } } } [HarmonyPatch(typeof(StoreGui), "Show")] public static class StoreGui_Show_Patch { private static void Postfix(StoreGui __instance) { if (TradersExtended.modEnabled.Value && IsOpen()) { TraderCoins.UpdateTraderCoinsVisibility(); UpdateNames(); ((TMP_InputField)playerFilter).SetTextWithoutNotify(""); ((TMP_InputField)traderFilter).SetTextWithoutNotify(""); SetStoreGuiPosition(); } } } [HarmonyPatch(typeof(StoreGui), "Hide")] public static class StoreGui_Hide_Patch { private static bool Prefix(Trader ___m_trader, float ___m_hideDistance) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) if (!TradersExtended.modEnabled.Value) { return true; } if (Vector3.Distance(((Component)___m_trader).transform.position, ((Component)Player.m_localPlayer).transform.position) > ___m_hideDistance) { return true; } if (AmountDialog.IsOpen()) { return false; } return true; } private static void Postfix() { if (TradersExtended.modEnabled.Value && !IsOpen()) { AmountDialog.Close(); TraderCoins.UpdateTraderCoins(); } } } [HarmonyPatch(typeof(StoreGui), "UpdateRecipeGamepadInput")] public static class StoreGui_UpdateRecipeGamepadInput_SellListGamepadNavigation { private static bool Prefix(StoreGui __instance, List<GameObject> ___m_itemList) { if (!TradersExtended.modEnabled.Value) { return true; } if (AmountDialog.IsOpen() || Console.IsVisible()) { return false; } if (ZInput.GetButtonDown("JoyButtonA") && ZInput.GetButton("JoyAltKeys")) { AmountDialog.Open(); ZInput.ResetButtonStatus("JoyButtonA"); return false; } if (ZInput.GetButtonDown("JoyDPadDown")) { if (GetSelectedItemIndex() != -1) { SelectItem(Mathf.Min(sellItemList.Count - 1, GetSelectedItemIndex() + 1), center: true); } else if (__instance.GetSelectedItemIndex() != -1) { __instance.SelectItem(Mathf.Min(___m_itemList.Count - 1, __instance.GetSelectedItemIndex() + 1), true); } } if (ZInput.GetButtonDown("JoyDPadUp")) { if (GetSelectedItemIndex() != -1) { SelectItem(Mathf.Max(0, GetSelectedItemIndex() - 1), center: true); } else if (__instance.GetSelectedItemIndex() != -1) { __instance.SelectItem(Mathf.Max(0, __instance.GetSelectedItemIndex() - 1), true); } } if (___m_itemList.Count > 0) { if (ZInput.GetButtonDown("JoyLStickDown")) { __instance.SelectItem(Mathf.Min(___m_itemList.Count - 1, __instance.GetSelectedItemIndex() + 1), true); } if (ZInput.GetButtonDown("JoyLStickUp")) { __instance.SelectItem(Mathf.Max(0, __instance.GetSelectedItemIndex() - 1), true); } if (ZInput.GetButtonDown("JoyDPadLeft") || ZInput.GetButtonDown("JoyRStickLeft")) { __instance.SelectItem(Mathf.Min(___m_itemList.Count - 1, Math.Max(__instance.GetSelectedItemIndex(), 0)), true); } } if (sellItemList.Count > 0) { if (ZInput.GetButtonDown("JoyDPadRight") || ZInput.GetButtonDown("JoyRStickRight")) { SelectItem(Mathf.Min(sellItemList.Count - 1, Math.Max(GetSelectedItemIndex(), 0)), center: true); } if (ZInput.GetButtonDown("JoyRStickDown")) { SelectItem(Mathf.Min(sellItemList.Count - 1, GetSelectedItemIndex() + 1), center: true); } if (ZInput.GetButtonDown("JoyRStickUp")) { SelectItem(Mathf.Max(0, GetSelectedItemIndex() - 1), center: true); } } return false; } } [HarmonyPatch(typeof(StoreGui), "SellItem")] public static class StoreGui_SellItem_SellItemFromSellableList { private static bool Prefix(StoreGui __instance) { if (!TradersExtended.modEnabled.Value) { return true; } if (!AmountDialog.IsOpen()) { SellSelectedItem(__instance); } return false; } } [HarmonyPatch(typeof(StoreGui), "GetSelectedItemIndex")] public static class StoreGui_GetSelectedItemIndex_GamePadScrollFix { private static bool Prefix(ref int __result, List<GameObject> ___m_itemList) { if (!TradersExtended.modEnabled.Value) { return true; } __result = -1; for (int i = 0; i < ___m_itemList.Count; i++) { if (((Component)___m_itemList[i].transform.Find("selected")).gameObject.activeSelf) { __result = i; break; } } return false; } } [HarmonyPatch(typeof(Chat), "HasFocus")] public static class Chat_HasFocus_ImpersonateChatFocus { private static void Postfix(ref bool __result) { if (TradersExtended.modEnabled.Value && (Object)(object)playerFilter != (Object)null && (Object)(object)traderFilter != (Object)null && StoreGui.IsVisible()) { __result = __result || ((TMP_InputField)playerFilter).isFocused || ((TMP_InputField)traderFilter).isFocused; } } } [HarmonyPatch(typeof(StoreGui), "SelectItem")] public static class StoreGui_SelectItem_FixOutOfRangeForEmptyList { private static void Prefix(StoreGui __instance, ref int index, ref bool center) { if (!TradersExtended.modEnabled.Value) { return; } if (index >= 0) { if (__instance.m_itemList.Count == 0) { index = -1; } else { index = Mathf.Clamp(index, 0, __instance.m_itemList.Count - 1); } } center = center || index == 0; if (index >= 0) { AmountDialog.SetSellState(sellDialog: false); SelectItem(-1, center: false); } } } [HarmonyPatch(typeof(StoreGui), "FillList")] public static class StoreGui_FillList_FillSellableList { private static readonly List<TradeItem> availableItems = new List<TradeItem>(); public static bool Prefix(StoreGui __instance) { //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) //IL_030d: Unknown result type (might be due to invalid IL or missing references) //IL_03ae: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03b9: Unknown result type (might be due to invalid IL or missing references) //IL_041f: Unknown result type (might be due to invalid IL or missing references) //IL_0425: Unknown result type (might be due to invalid IL or missing references) //IL_048b: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Expected O, but got Unknown //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_04ab: Unknown result type (might be due to invalid IL or missing references) //IL_04b0: Unknown result type (might be due to invalid IL or missing references) //IL_04b9: Unknown result type (might be due to invalid IL or missing references) //IL_04cb: Unknown result type (might be due to invalid IL or missing references) //IL_04e2: Unknown result type (might be due to invalid IL or missing references) if (!TradersExtended.modEnabled.Value) { return true; } int playerCoins = __instance.GetPlayerCoins(); int selectedItemIndex = __instance.GetSelectedItemIndex(); availableItems.Clear(); availableItems.AddRange(__instance.m_trader.GetAvailableItems()); foreach (GameObject item in __instance.m_itemList) { Object.Destroy((Object)(object)item); } __instance.m_itemList.Clear(); float num = (float)availableItems.Count * __instance.m_itemSpacing; num = Mathf.Max(__instance.m_itemlistBaseSize, num); __instance.m_listRoot.SetSizeWithCurrentAnchors((Axis)1, num); for (int i = 0; i < availableItems.Count; i++) { TradeItem val = availableItems[i]; bool flag = ItemToSell.IsBuyBackItem(val); ItemData val2 = (flag ? buybackItem.item : val.m_prefab.m_itemData); int num2 = (flag ? buybackItem.price : val.m_price); TradersExtended.TradeableItem.GetStackQualityFromStack(val.m_stack, out var stack, out var quality); if (flag) { if (buybackItem.itemType == ItemToSell.ItemType.Single) { stack = val2.m_stack; quality = val2.m_quality; } else if (buybackItem.itemType == ItemToSell.ItemType.Stack) { stack = buybackItem.stack; quality = buybackItem.quality; } else if (buybackItem.itemType == ItemToSell.ItemType.Combined) { stack = buybackItem.amount; quality = buybackItem.quality; } } GameObject element = Object.Instantiate<GameObject>(__instance.m_listElement, (Transform)(object)__instance.m_listRoot); element.SetActive(true); Transform transform = element.transform; RectTransform val3 = (RectTransform)(object)((transform is RectTransform) ? transform : null); Rect rect = __instance.m_listRoot.rect; float width = ((Rect)(ref rect)).width; rect = val3.rect; float num3 = (width - ((Rect)(ref rect)).width) / 2f; val3.anchoredPosition = new Vector2(num3, (float)i * (0f - __instance.m_itemSpacing) - num3); bool flag2 = num2 <= playerCoins; Image component = ((Component)element.transform.Find("icon")).GetComponent<Image>(); component.sprite = val2.GetIcon(); ((Graphic)component).color = (Color)((!flag2) ? new Color(1f, 0f, 1f, 0f) : (flag ? TradersExtended.colorBuybackHighlighted.Value : Color.white)); string text = Localization.instance.Localize(val2.m_shared.m_name); if (quality > 1) { text += $" <color=#add8e6ff>({quality})</color>"; } if (stack > 1) { text = text + " x" + stack; } TMP_Text component2 = ((Component)element.transform.Find("name")).GetComponent<TMP_Text>(); component2.text = text; ((Graphic)component2).color = ((!flag2) ? Color.grey : (flag ? TradersExtended.colorBuybackText.Value : Color.white)); string tooltip = ItemData.GetTooltip(val2, (quality == 0) ? val2.m_quality : quality, false, (float)val2.m_worldLevel, -1); element.GetComponent<UITooltip>().Set(val2.m_shared.m_name, tooltip, __instance.m_tooltipAnchor, default(Vector2)); TMP_Text component3 = ((Component)Utils.FindChild(element.transform, "price", (IterativeSearchType)0)).GetComponent<TMP_Text>(); component3.text = num2.ToString(); if (!flag2) { ((Graphic)component3).color = Color.grey; } ((UnityEvent)element.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { __instance.OnSelectedItem(element); }); if (flag) { ColorBlock colors = ((Selectable)element.GetComponent<Button>()).colors; ((ColorBlock)(ref colors)).normalColor = TradersExtended.colorBuybackNormal.Value; ((ColorBlock)(ref colors)).highlightedColor = TradersExtended.colorBuybackHighlighted.Value; ((Selectable)element.GetComponent<Button>()).colors = colors; } __instance.m_itemList.Add(element); } FillSellableList(__instance); __instance.SelectItem(Mathf.Clamp(selectedItemIndex, 0, __instance.m_itemList.Count - 1), false); return false; } } [HarmonyPatch(typeof(StoreGui), "BuySelectedItem")] public static class StoreGui_BuySelectedItem_TraderCoinsUpdate { public static bool isCalled; [HarmonyPriority(800)] public static bool Prefix(StoreGui __instance, ref Tuple<int, int> __state) { if (!TradersExtended.modEnabled.Value) { return true; } isCalled = true; if (__instance.m_selectedItem != null && __instance.CanAfford(__instance.m_selectedItem)) { if (BuyBackItem(__instance)) { return false; } TradersExtended.TradeableItem.GetStackQualityFromStack(__instance.m_selectedItem.m_stack, out var stack, out var quality); if (quality != 0) { __state = Tuple.Create(__instance.m_selectedItem.m_stack, __instance.m_selectedItem.m_prefab.m_itemData.m_quality); __instance.m_selectedItem.m_stack = stack; __instance.m_selectedItem.m_prefab.m_itemData.m_quality = quality; } } return true; } [HarmonyPriority(800)] public static void Postfix(StoreGui __instance, Tuple<int, int> __state) { isCalled = false; if (__state != null && __instance.m_selectedItem?.m_prefab?.m_itemData != null) { __instance.m_selectedItem.m_stack = __state.Item1; __instance.m_selectedItem.m_prefab.m_itemData.m_quality = __state.Item2; } } } [HarmonyPatch(typeof(Character), "ShowPickupMessage")] public static class Character_ShowPickupMessage_FixIncorrectStackMessage { private static void Prefix(ItemData item, ref int amount) { if (TradersExtended.modEnabled.Value && (Object)(object)StoreGui.instance != (Object)null && StoreGui_BuySelectedItem_TraderCoinsUpdate.isCalled && StoreGui.instance.m_selectedItem != null && item == StoreGui.instance.m_selectedItem.m_prefab?.m_itemData) { amount = StoreGui.instance.m_selectedItem.m_stack; } } } private const float positionDelta = 35f; private static GameObject sellPanel; private static Button sellButton; private static TMP_Text storeName; private static TMP_Text playerName; private static ScrollRectEnsureVisible itemEnsureVisible; private static RectTransform listRoot; private static GameObject listElement; private static RectTransform tooltipAnchor; private static GuiInputField traderFilter; private static GuiInputField playerFilter; internal static readonly List<GameObject> sellItemList = new List<GameObject>(); internal static readonly List<ItemToSell> tempItems = new List<ItemToSell>(); internal static readonly Dictionary<string, Dictionary<int, int>> tempItemsPrice = new Dictionary<string, Dictionary<int, int>>(); internal static ItemToSell selectedItem; private static int selectedItemIndex = -1; private static ItemToSell buybackItem; private static Func<bool> _adventureModeEnabled; private static Vector3 defaultStorePosition; public static bool AdventureModeEnabled(Trader trader) { return _adventureModeEnabled != null && Utils.GetPrefabName(((Component)trader).gameObject) == "Haldor" && _adventureModeEnabled(); } public static bool IsOpen() { return (Object)(object)sellPanel != (Object)null && sellPanel.gameObject.activeInHierarchy; } public static void OnSelectedItem(GameObject button) { int index = FindSelectedRecipe(button); SelectItem(index, center: false); AmountDialog.OnSelectedTradeableItemClick(sellDialog: true); } public static int FindSelectedRecipe(GameObject button) { for (int i = 0; i < sellItemList.Count; i++) { if ((Object)(object)sellItemList[i] == (Object)(object)button) { return i; } } return -1; } public static int GetSelectedItemIndex() { int result = -1; for (int i = 0; i < tempItems.Count; i++) { if (tempItems[i] == selectedItem) { result = i; } } return result; } public static void SelectItem(int index, bool center) { if (sellItemList.Count == 0 || index >= sellItemList.Count) { index = -1; } center = center || index == 0; for (int i = 0; i < sellItemList.Count; i++) { GameObject obj = sellItemList[i]; if (obj != null) { Transform obj2 = obj.transform.Find("selected"); if (obj2 != null) { ((Component)obj2).gameObject.SetActive(i == index); } } } if (center && index >= 0 && (Object)(object)sellItemList[index] != (Object)null) { ScrollRectEnsureVisible obj3 = itemEnsureVisible; if (obj3 != null) { ? val = obj3; Transform transform = sellItemList[index].transform; ((ScrollRectEnsureVisible)val).CenterOnItem((RectTransform)(object)((transform is RectTransform) ? transform : null)); } } selectedItem = ((index < 0) ? null : tempItems[index]); if (index >= 0) { AmountDialog.SetSellState(sellDialog: true); StoreGui.instance.SelectItem(-1, false); } } public static void SellSelectedItem(StoreGui __instance) { //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_036c: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0294: Unknown result type (might be due to invalid IL or missing references) //IL_0299: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a3: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Unknown result type (might be due to invalid IL or missing references) //IL_02aa: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) ItemDrop coinPrefab = __instance.m_coinPrefab; if ((Object)(object)coinPrefab == (Object)null) { TradersExtended.logger.LogWarning((object)"No m_coinPrefab set in StoreGui"); } else { if (selectedItem == null) { return; } selectedItemIndex = GetSelectedItemIndex(); if (TradersExtended.enableBuyBack.Value) { buybackItem = selectedItem.Clone(); } if (selectedItem.itemType == ItemToSell.ItemType.Single) { ((Humanoid)Player.m_localPlayer).GetInventory().RemoveItem(selectedItem.item); } else if (selectedItem.itemType == ItemToSell.ItemType.Stack) { ((Humanoid)Player.m_localPlayer).GetInventory().RemoveItem(selectedItem.item.m_shared.m_name, selectedItem.stack, (selectedItem.quality == 0) ? (-1) : selectedItem.quality, true); } else if (selectedItem.itemType == ItemToSell.ItemType.Combined) { ((Humanoid)Player.m_localPlayer).GetInventory().RemoveItem(selectedItem.item.m_shared.m_name, selectedItem.amount, (selectedItem.quality == 0) ? (-1) : selectedItem.quality, true); } int num = ((Humanoid)Player.m_localPlayer).GetInventory().CountItems(coinPrefab.m_itemData.m_shared.m_name, -1, true); if (((Humanoid)Player.m_localPlayer).GetInventory().AddItem(((Object)((Component)coinPrefab).gameObject).name, selectedItem.price, coinPrefab.m_itemData.m_quality, coinPrefab.m_itemData.m_variant, 0L, "", false) == null) { int num2 = selectedItem.price + num - ((Humanoid)Player.m_localPlayer).GetInventory().CountItems(coinPrefab.m_itemData.m_shared.m_name, -1, true); int num3 = num2 / coinPrefab.m_itemData.m_shared.m_maxStackSize; GameObject prefab = ZNetScene.instance.GetPrefab(((Object)((Component)coinPrefab).gameObject).name); if (Object.op_Implicit((Object)(object)prefab)) { ((Character)Player.m_localPlayer).Message((MessageType)1, "$msg_dropped: $item_coins x" + num2, 0, (Sprite)null); while (num2 > 0) { Vector3 val = Random.insideUnitSphere * ((num3 == 1) ? 0f : 0.5f); GameObject val2 = Object.Instantiate<GameObject>(prefab, ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 2f + Vector3.up + val, Quaternion.identity); ItemDrop component = val2.GetComponent<ItemDrop>(); component.m_itemData.m_stack = Mathf.Min(num2, component.m_itemData.m_shared.m_maxStackSize); num2 -= component.m_itemData.m_stack; } } } string text = ((selectedItem.stack <= 1) ? selectedItem.item.m_shared.m_name : $"{selectedItem.stack}x{selectedItem.item.m_shared.m_name}"); __instance.m_sellEffects.Create(((Component)__instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1); ((Character)Player.m_localPlayer).Message((MessageType)1, Localization.instance.Localize("$msg_sold", new string[2] { text, selectedItem.price.ToString() }), 0, selectedItem.item.GetIcon()); __instance.m_trader.OnSold(); Gogan.LogEvent("Game", "SoldItem", text, 0L); __instance.FillList(); } } private static void AddItemToSellList(TradersExtended.TradeableItem item) { if (item.price != 0 && item.stack != 0 && (string.IsNullOrEmpty(item.requiredGlobalKey) || !(from s in item.requiredGlobalKey.Split(new char[1] { ',' }) select s.Trim() into s where !Utility.IsNullOrWhiteSpace(s) select s).Any((string s) => !ZoneSystem.instance.GetGlobalKey(s))) && (string.IsNullOrEmpty(item.notRequiredGlobalKey) || !(from s in item.notRequiredGlobalKey.Split(new char[1] { ',' }) select s.Trim() into s where !Utility.IsNullOrWhiteSpace(s) select s).Any((string s) => ZoneSystem.instance.GetGlobalKey(s))) && (string.IsNullOrEmpty(item.requiredPlayerKey) || !(from s in item.requiredPlayerKey.Split(new char[1] { ',' }) select s.Trim() into s where !Utility.IsNullOrWhiteSpace(s) select s).Any((string s) => !((Humanoid)Player.m_localPlayer).HaveUniqueKey(s))) && (string.IsNullOrEmpty(item.notRequiredPlayerKey) || !(from s in item.notRequiredPlayerKey.Split(new char[1] { ',' }) select s.Trim() into s where !Utility.IsNullOrWhiteSpace(s) select s).Any((string s) => ((Humanoid)Player.m_localPlayer).HaveUniqueKey(s))) && TryGetPriceKey(item, out var key)) { if (!tempItemsPrice.ContainsKey(key)) { tempItemsPrice[key] = new Dictionary<int, int>(); } tempItemsPrice[key][item.stack] = item.price; } } private static bool TryGetPriceKey(TradersExtended.TradeableItem item, out string key) { key = ""; GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(item.prefab); if ((Object)(object)itemPrefab == (Object)null) { return false; } ItemData itemData = itemPrefab.GetComponent<ItemDrop>().m_itemData; if (itemData.m_shared.m_maxStackSize == 1 && item.stack != 1) { return false; } key = GetPriceKey(itemData, item.quality); return true; } private static string GetPriceKey(ItemData itemData, int quality) { return (quality > 0) ? (itemData.m_shared.m_name + "-" + quality) : itemData.m_shared.m_name; } private static bool IgnoreItemForSell(ItemData item) { if (item.m_shared.m_name == StoreGui.instance.m_coinPrefab.m_itemData.m_shared.m_name) { return true; } if (!string.IsNullOrWhiteSpace(((TMP_InputField)playerFilter).text) && Localization.instance.Localize(item.m_shared.m_name).ToLower().IndexOf(((TMP_InputField)playerFilter).text.ToLower()) == -1) { return true; } if (TradersExtended.hideEquippedAndHotbarItems.Value && item.m_equipped) { return true; } if (TradersExtended.hideEquippedAndHotbarItems.Value && item.m_gridPos.y == 0 && item.IsEquipable()) { return true; } if (TradersExtended.hideEquippedAndHotbarItems.Value && (from func in AzuExtendedPlayerInventory.API.GetSlots().GetItemFuncs where func != null select func(Player.m_localPlayer)).Contains(item)) { return true; } if (TradersExtended.hideEquippedAndHotbarItems.Value && ExtraSlots.API.GetAllExtraSlotsItems().Contains(item)) { return true; } return false; } private static Dictionary<int, int> GetStackPrices(ItemData item, out int quality) { quality = item.m_quality; string priceKey = GetPriceKey(item, quality); if (tempItemsPrice.ContainsKey(priceKey)) { return tempItemsPrice[priceKey]; } quality = 0; priceKey = GetPriceKey(item, quality); if (tempItemsPrice.ContainsKey(priceKey)) { return tempItemsPrice[priceKey]; } return null; } private static void AddToSellList(ItemData item, int itemStack, int itemPrice, float priceFactor, int quality, ItemToSell.ItemType itemType) { int price = itemPrice; if (itemType == ItemToSell.ItemType.Combined) { price *= itemStack; } if (itemType != ItemToSell.ItemType.Stack && TradersExtended.qualityMultiplier.Value != 0f && quality == 0 && item.m_quality > 1) { price += (int)(TradersExtended.qualityMultiplier.Value * (float)price * (float)(item.m_quality - 1)); } price = Math.Max((int)((float)price * priceFactor), 1); if (itemType == ItemToSell.ItemType.Single) { tempItems.Add(new ItemToSell { itemType = itemType, item = item, stack = itemStack, price = price, quality = quality }); } else if (itemType == ItemToSell.ItemType.Stack) { ItemToSell itemToSell = tempItems.Find((ItemToSell tmpItem) => tmpItem.itemType == itemType && tmpItem.stack == itemStack && tmpItem.item.m_shared.m_name == item.m_shared.m_name && (quality == 0 || tmpItem.item.m_quality == quality) && tmpItem.price == price); if (itemToSell != null) { itemToSell.amount += item.m_stack; return; } tempItems.Add(new ItemToSell { itemType = itemType, item = item, stack = itemStack, price = price, amount = item.m_stack, quality = quality }); } else if (itemType == ItemToSell.ItemType.Combined) { ItemToSell itemToSell2 = tempItems.Find((ItemToSell tmpItem) => tmpItem.itemType == itemType && tmpItem.item.m_shared.m_name == item.m_shared.m_name && (quality == 0 || tmpItem.item.m_quality == quality) && tmpItem.stack == 1); if (itemToSell2 != null) { itemToSell2.price += price; itemToSell2.amount += itemStack; return; } tempItems.Add(new ItemToSell { itemType = itemType, item = item, stack = 1, price = price, amount = itemStack, quality = quality, pricePerItem = itemPrice + ((TradersExtended.qualityMultiplier.Value != 0f && quality == 0 && item.m_quality > 1) ? ((int)(TradersExtended.qualityMultiplier.Value * (float)itemPrice * (float)(item.m_quality - 1))) : 0) }); } } public static void FillSellableList(StoreGui __instance) { //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: 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_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_0391: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_049f: Unknown result type (might be due to invalid IL or missing references) //IL_04a5: Unknown result type (might be due to invalid IL or missing references) //IL_0519: Unknown result type (might be due to invalid IL or missing references) //IL_0523: Expected O, but got Unknown //IL_04f5: Unknown result type (might be due to invalid IL or missing references) foreach (GameObject sellItem in sellItemList) { Object.Destroy((Object)(object)sellItem); } sellItemList.Clear(); tempItems.Clear(); tempItemsPrice.Clear(); if (TradersExtended.sellableItems.ContainsKey(TradersExtended.TraderListKey(__instance.m_trader, TradersExtended.ItemsListType.Sell))) { TradersExtended.sellableItems[TradersExtended.TraderListKey(__instance.m_trader, TradersExtended.ItemsListType.Sell)].ForEach(delegate(TradersExtended.TradeableItem item) { AddItemToSellList(item); }); } if (TradersExtended.sellableItems.ContainsKey(TradersExtended.CommonListKey(TradersExtended.ItemsListType.Sell))) { TradersExtended.sellableItems[TradersExtended.CommonListKey(TradersExtended.ItemsListType.Sell)].ForEach(delegate(TradersExtended.TradeableItem item) { AddItemToSellList(item); }); } float priceFactor = TraderCoins.GetPriceFactor(buyPrice: false); foreach (ItemData item in ((Humanoid)Player.m_localPlayer).GetInventory().GetAllItemsSortedByName()) { if (IgnoreItemForSell(item)) { continue; } int quality; Dictionary<int, int> stackPrices = GetStackPrices(item, out quality); if (stackPrices == null) { continue; } foreach (int item2 in stackPrices.Keys.OrderBy((int x) => x)) { if (item2 == 1) { if (item.m_shared.m_maxStackSize == 1) { AddToSellList(item, 1, stackPrices[item2], priceFactor, quality, ItemToSell.ItemType.Single); } else { AddToSellList(item, item.m_stack, stackPrices[item2], priceFactor, quality, ItemToSell.ItemType.Combined); } } else { AddToSellList(item, item2, stackPrices[item2], priceFactor, quality, ItemToSell.ItemType.Stack); } } } tempItems.RemoveAll((ItemToSell x) => x.amount != 0 && x.amount < x.stack); float num = (float)tempItems.Count * __instance.m_itemSpacing; num = Mathf.Max(__instance.m_itemlistBaseSize, num); listRoot.SetSizeWithCurrentAnchors((Axis)1, num); for (int i = 0; i < tempItems.Count; i++) { ItemToSell itemToSell = tempItems[i]; GameObject element = Object.Instantiate<GameObject>(listElement, (Transform)(object)listRoot); element.SetActive(true); Transform transform = element.transform; RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); Rect rect = __instance.m_listRoot.rect; float width = ((Rect)(ref rect)).width; rect = val.rect; float num2 = (width - ((Rect)(ref rect)).width) / 2f; val.anchoredPosition = new Vector2(num2, (float)i * (0f - __instance.m_itemSpacing) - num2); bool flag = TraderCoins.CanSell(itemToSell.price); Image component = ((Component)element.transform.Find("icon")).GetComponent<Image>(); component.sprite = itemToSell.item.GetIcon(); ((Graphic)component).color = (Color)(flag ? Color.white : new Color(1f, 0f, 1f, 0f)); string text = Localization.instance.Localize(itemToSell.item.m_shared.m_name); if (itemToSell.quality > 1) { text += $" <color=#add8e6ff>({itemToSell.quality})</color>"; } if (itemToSell.stack > 1) { text = text + " x" + itemToSell.stack; } if (itemToSell.amount > itemToSell.stack) { text += $" <color=#c0c0c0ff>({itemToSell.amount})</color>"; } TMP_Text component2 = ((Component)element.transform.Find("name")).GetComponent<TMP_Text>(); component2.SetText(text); element.GetComponent<UITooltip>().Set(itemToSell.item.m_shared.m_name, itemToSell.item.GetTooltip(-1), tooltipAnchor, default(Vector2)); TMP_Text component3 = ((Component)element.transform.Find("coin_bkg").Find("price")).GetComponent<TMP_Text>(); component3.SetText(itemToSell.price.ToString()); if (!flag) { ((Graphic)component3).color = Color.grey; } ((UnityEvent)element.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { OnSelectedItem(element); }); sellItemList.Add(element); } if (selectedItemIndex == -1) { selectedItemIndex = GetSelectedItemIndex(); } SelectItem(Mathf.Min(tempItems.Count - 1, selectedItemIndex), center: false); } public static void UpdateSellButton() { ((Selectable)sellButton).interactable = selectedItem != null && TraderCoins.CanSell(selectedItem.price); } public static bool BuyBackItem(StoreGui store) { //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) if (!ItemToSell.IsBuyBackItem(store.m_selectedItem)) { return false; } bool flag; if (buybackItem.itemType == ItemToSell.ItemType.Single) { flag = ((Humanoid)Player.m_localPlayer).GetInventory().AddItem(buybackItem.item); } else { int variant = buybackItem.item.m_variant; int num = ((buybackItem.quality == 0) ? buybackItem.item.m_quality : buybackItem.quality); int num2 = ((buybackItem.itemType == ItemToSell.ItemType.Stack) ? buybackItem.stack : buybackItem.amount); Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory(); GameObject dropPrefab = buybackItem.item.m_dropPrefab; flag = inventory.AddItem((dropPrefab != null) ? ((Object)dropPrefab).name : null, num2, num, variant, buybackItem.item.m_crafterID, buybackItem.item.m_crafterName, buybackItem.item.m_pickedUp) != null; } if (flag) { buybackItem = null; ((Humanoid)Player.m_localPlayer).GetInventory().RemoveItem(StoreGui.instance.m_coinPrefab.m_itemData.m_shared.m_name, store.m_selectedItem.m_price, -1, true); store.m_selectedItem = null; StoreGui.instance.m_buyEffects.Create(((Component)StoreGui.instance).transform.position, Quaternion.identity, (Transform)null, 1f, -1); StoreGui.instance.FillList(); } return flag; } public static void SetStoreGuiPosition() { //IL_002a: 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_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_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) if (!((Object)(object)StoreGui.instance == (Object)null) && !((Object)(object)StoreGui.instance.m_rootPanel == (Object)null)) { if (defaultStorePosition == Vector3.zero) { defaultStorePosition = StoreGui.instance.m_rootPanel.transform.localPosition; } if (TradersExtended.fixedStoreGuiPosition.Value != Vector2.zero) { StoreGui.instance.m_rootPanel.transform.localPosition = Vector2.op_Implicit(TradersExtended.fixedStoreGuiPosition.Value); } else { StoreGui.instance.m_rootPanel.transform.localPosition = (AdventureModeEnabled(StoreGui.instance.m_trader) ? (defaultStorePosition - new Vector3(RepairPanel.TraderCanRepair(StoreGui.instance.m_trader) ? 146f : 100f, 0f, 0f)) : defaultStorePosition); } } } private static void AddAvailableItems(string listKey, List<TradeItem> __result) { if (TradersExtended.tradeableItems.ContainsKey(listKey)) { CollectionExtensions.DoIf<TradersExtended.TradeableItem>((IEnumerable<TradersExtended.TradeableItem>)TradersExtended.tradeableItems[listKey], (Func<TradersExtended.TradeableItem, bool>)((TradersExtended.TradeableItem item) => item.IsItemToSell()), (Action<TradersExtended.TradeableItem>)delegate(TradersExtended.TradeableItem item) { __result.Add(item.ToTradeItem()); }); } } public static void UpdateNames() { Trader trader = StoreGui.instance.m_trader; string text = ((trader != null) ? trader.GetHoverName() : null); string text2 = Player.m_localPlayer.GetPlayerName(); if (TradersExtended.traderUseCoins.Value && TradersExtended.traderUseFlexiblePricing.Value) { text += GetPriceFactorString(TraderCoins.GetPriceFactor(buyPrice: true), reversed: true); text2 += GetPriceFactorString(TraderCoins.GetPriceFactor(buyPrice: false)); } storeName.SetText(text); playerName.SetText(text2); static string GetPriceFactorString(float factor, bool reversed = false) { if (factor == 1f) { return ""; } return string.Format(" · <color=#{0}>{1:+0;-0}</color>%", ((reversed && factor < 1f) || (!reversed && factor > 1f)) ? "80ff80fc" : "ff6464fc", (factor - 1f) * 100f); } } } internal static class RepairPanel { [HarmonyPatch(typeof(ObjectDB), "Awake")] public static class ObjectDB_Awake_GetRepairEffect { [HarmonyPriority(0)] private static void Postfix(List<Recipe> ___m_recipes) { if (!TradersExtended.modEnabled.Value) { return; } foreach (Recipe ___m_recipe in ___m_recipes) { CraftingStation craftingStation = ___m_recipe.m_craftingStation; if (((craftingStation != null) ? ((Object)craftingStation).name : null) == "piece_workbench" && ___m_recipe.m_craftingStation.m_repairItemDoneEffects != null) { repairItemDoneEffects = ___m_recipe.m_craftingStation.m_repairItemDoneEffects; break; } } } } private const string s_stationEffectName = "piece_workbench"; private static GameObject repairPanel; private static Button repairButton; private static EffectList repairItemDoneEffects; public static GameObject RepurposeSellButton(StoreGui storeGui) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: 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_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) repairPanel = ((Component)storeGui.m_rootPanel.transform.Find("SellPanel")).gameObject; repairPanel.transform.localPosition = new Vector3(592f, -603f, 0f); repairButton = ((Component)repairPanel.transform.Find("SellButton")).GetComponent<Button>(); ((UnityEventBase)repairButton.onClick).SetPersistentListenerState(0, (UnityEventCallState)0); ((UnityEvent)repairButton.onClick).AddListener((UnityAction)delegate { OnRepairPressed(storeGui); }); ButtonImageColor component = ((Component)repairButton).GetComponent<ButtonImageColor>(); component.m_defaultColor = new Color(0f, 0f, 0f, 0.85f); component.m_disabledColor = new Color(0f, 0f, 0f, 0.5f); Image component2 = ((Component)((Component)repairButton).transform.Find("Image")).GetComponent<Image>(); component2.overrideSprite = ((Component)((Component)InventoryGui.instance.m_repairButton).transform.Find("Image")).GetComponent<Image>().sprite; ((Component)component2).transform.localScale = Vector3.one * 0.85f; ((Component)component2).transform.localPosition = new Vector3(1f, -1.5f, 0f); ((Component)repairButton).GetComponent<UITooltip>().Set("", "$inventory_repairbutton", (RectTransform)null, default(Vector2)); Update(storeGui); return repairPanel; } public static void AddButtonBlocker(GameObject blocker) { ((Component)repairButton).GetComponent<UIGamePad>().m_blockingElements.Add(blocker); } public static bool TraderCanRepair(Trader trader) { return TradersExtended.traderRepair.Value && (TradersExtended._tradersToRepairWeapons.Contains(TradersExtended.TraderName(trader)) || TradersExtended._tradersToRepairArmor.Contains(TradersExtended.TraderName(trader))); } public static void Update(StoreGui storeGui) { if (!((Object)(object)StoreGui.instance == (Object)null) && StorePanel.IsOpen()) { repairPanel.SetActive(TraderCanRepair(storeGui.m_trader)); ((Selectable)repairButton).interactable = HaveRepairableItems(storeGui); } } public static void OnRepairPressed(StoreGui storeGui) { RepairOneItem(storeGui); Update(storeGui); } public static void RepairOneItem(StoreGui storeGui) { //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null) { return; } ItemData itemToRepair = GetItemToRepair(storeGui); if (itemToRepair == null) { ((Character)Player.m_localPlayer).Message((MessageType)2, Player.m_localPlayer.GetPlayerName() + " $msg_doesnotneedrepair", 0, (Sprite)null); return; } if (storeGui.GetPlayerCoins() < Math.Abs(TradersExtended.traderRepairCost.Value)) { ((Character)Player.m_localPlayer).Message((MessageType)2, "$msg_outof $item_coins", 0, (Sprite)null); return; } itemToRepair.m_durability = itemToRepair.GetMaxDurability(); if (TradersExtended.traderRepairCost.Value != 0) { ((Humanoid)Player.m_localPlayer).GetInventory().RemoveItem(storeGui.m_coinPrefab.m_itemData.m_shared.m_name, Math.Abs(TradersExtended.traderRepairCost.Value), -1, true); } EffectList obj = repairItemDoneEffects; if (obj != null) { obj.Create(((Component)Player.m_localPlayer).transform.position, Quaternion.identity, (Transform)null, 1f, -1); } storeGui.m_sellEffects.Create(((Component)storeGui).transform.position, Quaternion.identity, (Transform)null, 1f, -1); ((Character)Player.m_localPlayer).Message((MessageType)2, Localization.instance.Localize("$msg_repaired", new string[1] { itemToRepair.m_shared.m_name }), 0, (Sprite)null); } public static bool HaveRepairableItems(StoreGui storeGui) { return GetItemToRepair(storeGui) != null; } public static ItemData GetItemToRepair(StoreGui storeGui) { if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)storeGui == (Object)null || (Object)(object)storeGui.m_trader == (Object)null) { return null; } InventoryGui.instance.m_tempWornItems.Clear(); ((Humanoid)Player.m_localPlayer).GetInventory().GetWornItems(InventoryGui.instance.m_tempWornItems); foreach (ItemData tempWornItem in InventoryGui.instance.m_tempWornItems) { if (tempWornItem.m_shared.m_canBeReparied && IsCapableOfRepair(storeGui.m_trader, tempWornItem)) { return tempWornItem; } } return null; } private static bool IsCapableOfRepair(Trader trader, ItemData item) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Invalid comparison between Unknown and I4 //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Invalid comparison between Unknown and I4 //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Invalid comparison between Unknown and I4 //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Invalid comparison between Unknown and I4 //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Invalid comparison between Unknown and I4 //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Invalid comparison between Unknown and I4 //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Invalid comparison between Unknown and I4 if ((int)item.m_shared.m_itemType == 3 || (int)item.m_shared.m_itemType == 20 || (int)item.m_shared.m_itemType == 4 || (int)item.m_shared.m_itemType == 5 || (int)item.m_shared.m_itemType == 19 || (int)item.m_shared.m_itemType == 15 || (int)item.m_shared.m_itemType == 14 || (int)item.m_shared.m_itemType == 22) { return TradersExtended._tradersToRepairWeapons.Contains(TradersExtended.TraderName(trader)); } if ((int)item.m_shared.m_itemType == 6 || (int)item.m_shared.m_itemType == 7 || (int)item.m_shared.m_itemType == 11 || (int)item.m_shared.m_itemType == 17 || (int)item.m_shared.m_itemType == 18 || (int)item.m_shared.m_itemType == 10) { return TradersExtended._tradersToRepairArmor.Contains(TradersExtended.TraderName(trader)); } return false; } } [BepInPlugin("shudnal.TradersExtended", "Traders Extended", "1.3.12")] [BepInIncompatibility("randyknapp.mods.auga")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class TradersExtended : BaseUnityPlugin { [Serializable] public class TradeableItem { public const int qualityStackMultiplier = 1000000; public string prefab; public int stack = 1; public int price = 1; public int quality = 0; public string requiredGlobalKey = ""; public string notRequiredGlobalKey = ""; public string requiredPlayerKey = ""; public string notRequiredPlayerKey = ""; [NonSerialized] public ItemDrop itemDrop; public bool IsItemToSell() { if (!Object.op_Implicit((Object)(object)ZoneSystem.instance) || !Object.op_Implicit((Object)(object)ObjectDB.instance) || !Object.op_Implicit((Object)(object)Player.m_localPlayer)) { return false; } if (!string.IsNullOrEmpty(requiredGlobalKey) && (from s in requiredGlobalKey.Split(new char[1] { ',' }) select s.Trim() into s where !Utility.IsNullOrWhiteSpace(s) select s).Any((string s) => !ZoneSystem.instance.GetGlobalKey(s))) { return false; } if (!string.IsNullOrEmpty(notRequiredGlobalKey) && (from s in notRequiredGlobalKey.Split(new char[1] { ',' }) select s.Trim() into s where !Utility.IsNullOrWhiteSpace(s) select s).Any((string s) => ZoneSystem.instance.GetGlobalKey(s))) { return false; } if (!string.IsNullOrEmpty(requiredPlayerKey) && (from s in requiredPlayerKey.Split(new char[1] { ',' }) select s.Trim() into s where !Utility.IsNullOrWhiteSpace(s) select s).Any((string s) => !((Humanoid)Player.m_localPlayer).HaveUniqueKey(s))) { return false; } if (!string.IsNullOrEmpty(notRequiredPlayerKey) && (from s in notRequiredPlayerKey.Split(new char[1] { ',' }) select s.Trim() into s where !Utility.IsNullOrWhiteSpace(s) select s).Any((string s) => ((Humanoid)Player.m_localPlayer).HaveUniqueKey(s))) { return false; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefab); if ((Object)(object)itemPrefab == (Object)null || !itemPrefab.TryGetComponent<ItemDrop>(ref itemDrop)) { return false; } return !checkForDiscovery.Value || IgnoreItemDiscovery(prefab.ToLower()) || Player.m_localPlayer.IsMaterialKnown(itemDrop.m_itemData.m_shared.m_name); } public TradeItem ToTradeItem() { //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_0041: 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Expected O, but got Unknown if ((Object)(object)itemDrop == (Object)null) { GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefab); itemDrop = itemPrefab.GetComponent<ItemDrop>(); } return new TradeItem { m_prefab = itemDrop, m_price = price, m_stack = GetStackFromStackQuality(stack, quality), m_requiredGlobalKey = requiredGlobalKey }; } public static void NormalizeStack(TradeItem item) { GetStackQualityFromStack(item.m_stack, out var num, out var num2); item.m_stack = GetStackFromStackQuality(Mathf.Clamp(num, 1, item.m_prefab.m_itemData.m_shared.m_maxStackSize), num2); } public static void GetStackQualityFromStack(int m_stack, out int stack, out int quality) { stack = m_stack % 1000000; quality = m_stack / 1000000; } public static int GetStackFromStackQuality(int stack, int quality) { return stack + 1000000 * quality; } public static int GetStackFromStack(int m_stack) { return m_stack % 1000000; } } public enum ItemsListType { Buy, Sell } public class ItemToExport { public string p; public string n; public int se; public int b; public int s; public string f; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static EventHandler <>9__54_0; public static EventHandler <>9__54_1; public static EventHandler <>9__54_2; public static EventHandler <>9__54_3; public static EventHandler <>9__54_4; public static ConsoleEvent <>9__57_0; public static ConsoleOptionsFetcher <>9__57_1; public static ConsoleEventFailable <>9__57_2; public static ConsoleOptionsFetcher <>9__57_3; public static Action<ItemToExport> <>9__60_0; public static Func<Humanoid, bool> <>9__60_1; public static Func<ItemToExport, string> <>9__60_2; public static Func<ItemToExport, string> <>9__60_3; public static Func<string, string> <>9__61_0; public static Func<string, bool> <>9__61_1; public static Func<string, string> <>9__61_2; public static Func<string, bool> <>9__61_3; public static Func<string, string> <>9__61_4; public static Func<string, bool> <>9__61_5; public static Func<bool> <>9__69_0; internal void <ConfigInit>b__54_0(object sender, EventArgs args) { FillConfigLists(); } internal void <ConfigInit>b__54_1(object sender, EventArgs args) { FillConfigLists(); } internal void <ConfigInit>b__54_2(object sender, EventArgs args) { FillConfigLists(); } internal void <ConfigInit>b__54_3(object sender, EventArgs args) { StartConfigLoad(); } internal void <ConfigInit>b__54_4(object sender, EventArgs args) { StorePanel.SetStoreGuiPosition(); } internal void <InitCommands>b__57_0(ConsoleEventArgs args) { if (args.Length >= 2) { string text = args.FullLine.Substring(args[0].Length + 1); if (text == "save") { SaveFromObjectDB(args.Context); } else if (text == "itemlist") { ExportItemListFromObjectDB(args.Context); } } else { args.Context.AddString("Actions: save - Save full item list into config folder, itemlist - Save filtered item list into config folder"); } } internal List<string> <InitCommands>b__57_1() { return new List<string> { "save", "itemlist" }; } internal object <InitCommands>b__57_2(ConsoleEventArgs args) { if (args.Length <= 1) { return false; } TraderCoins.SetTraderCoins(StringExtensionMethods.GetStableHashCode(args[1]), args.TryParameterInt(2, traderCoinsMinimumAmount.Value)); return true; } internal List<string> <InitCommands>b__57_3() { return TraderCoins.GetTraderPrefabs(); } internal void <ExportItemListFromObjectDB>b__60_0(ItemToExport item) { LogInfo(item.p + " " + item.f); } internal bool <ExportItemListFromObjectDB>b__60_1(Humanoid human) { BaseAI val = default(BaseAI); return ((Component)human).TryGetComponent<BaseAI>(ref val); } internal string <ExportItemListFromObjectDB>b__60_2(ItemToExport item) { return item.p; } internal string <ExportItemListFromObjectDB>b__60_3(ItemToExport item) { return item.f; } internal string <FillConfigLists>b__61_0(string p) { return p.Trim().ToLower(); } internal bool <FillConfigLists>b__61_1(string p) { return !string.IsNullOrWhiteSpace(p); } internal string <FillConfigLists>b__61_2(string p) { return TraderName(p.Trim()); } internal bool <FillConfigLists>b__61_3(string p) { return !string.IsNullOrWhiteSpace(p); } internal string <FillConfigLists>b__61_4(string p) { return TraderName(p.Trim()); } internal bool <FillConfigLists>b__61_5(string p) { return !string.IsNullOrWhiteSpace(p); } internal bool <AddCommonValuableItems>b__69_0() { return Object.op_Implicit((Object)(object)ObjectDB.instance); } } [CompilerGenerated] private sealed class <AddCommonValuableItems>d__69 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private string <listKey>5__1; private int <itemsCount>5__2; private List<GameObject>.Enumerator <>s__3; private GameObject <prefab>5__4; private ItemDrop <itemDrop>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <AddCommonValuableItems>d__69(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <listKey>5__1 = null; <>s__3 = default(List<GameObject>.Enumerator); <prefab>5__4 = null; <itemDrop>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitUntil((Func<bool>)(() => Object.op_Implicit((Object)(object)ObjectDB.instance))); <>1__state = 1; return true; case 1: <>1__state = -1; <listKey>5__1 = CommonListKey(ItemsListType.Sell); if (!sellableItems.ContainsKey(<listKey>5__1)) { sellableItems[<listKey>5__1] = new List<TradeableItem>(); } <itemsCount>5__2 = sellableItems[<listKey>5__1].Count; <>s__3 = ObjectDB.instance.m_items.GetEnumerator(); try { while (<>s__3.MoveNext()) { <prefab>5__4 = <>s__3.Current; if (<prefab>5__4.TryGetComponent<ItemDrop>(ref <itemDrop>5__5) && <itemDrop>5__5.m_itemData.m_shared.m_value > 0 && !IsItemInSellList(((Object)<prefab>5__4).name)) { sellableItems[<listKey>5__1].Add(new TradeableItem { prefab = ((Object)<prefab>5__4).name, price = <itemDrop>5__5.m_itemData.m_shared.m_value }); <itemDrop>5__5 = null; <prefab>5__4 = null; } } } finally { ((IDisposable)<>s__3).Dispose(); } <>s__3 = default(List<GameObject>.Enumerator); LogInfo($"Loaded {sellableItems[<listKey>5__1].Count - <itemsCount>5__2} common valuable items from ObjectDB"); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <LoadConfigs>d__66 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; private Dictionary<string, string>.Enumerator <>s__1; private KeyValuePair<string, string> <configJSON>5__2; private string[] <configKey>5__3; private string <trader>5__4; private ItemsListType <list>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LoadConfigs>d__66(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>s__1 = default(Dictionary<string, string>.Enumerator); <configJSON>5__2 = default(KeyValuePair<string, string>); <configKey>5__3 = null; <trader>5__4 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; tradeableItems.Clear(); sellableItems.Clear(); <>s__1 = configsJSON.Value.GetEnumerator(); try { while (<>s__1.MoveNext()) { <configJSON>5__2 = <>s__1.Current; <configKey>5__3 = <configJSON>5__2.Key.Split(new char[1] { '.' }); <trader>5__4 = <configKey>5__3[0]; Enum.TryParse<ItemsListType>(<configKey>5__3[1], ignoreCase: true, out <list>5__5); if (<list>5__5 == ItemsListType.Buy) { LoadTradeableItems(<configJSON>5__2.Value, <trader>5__4); } else { LoadSellableItems(<configJSON>5__2.Value, <trader>5__4); } <configKey>5__3 = null; <trader>5__4 = null; <configJSON>5__2 = default(KeyValuePair<string, string>); } } finally { ((IDisposable)<>s__1).Dispose(); } <>s__1 = default(Dictionary<string, string>.Enumerator); if (addCommonValuableItemsToSellList.Value) { <>2__current = AddCommonValuableItems(); <>1__state = 1; return true; } break; case 1: <>1__state = -1; break; } return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string pluginID = "shudnal.TradersExtended"; public const string pluginName = "Traders Extended"; public const string pluginVersion = "1.3.12"; private readonly Harmony harmony = new Harmony("shudnal.TradersExtended"); internal static readonly ConfigSync configSync = new ConfigSync("shudnal.TradersExtended") { DisplayName = "Traders Extended", CurrentVersion = "1.3.12", MinimumRequiredVersion = "1.3.12" }; public static ManualLogSource logger; internal static TradersExtended instance; public static ConfigEntry<bool> modEnabled; private static ConfigEntry<bool> loggingEnabled; private static ConfigEntry<bool> configLocked; public static ConfigEntry<bool> checkForDiscovery; private static ConfigEntry<string> checkForDiscoveryIgnoreItems; public static ConfigEntry<bool> traderRepair; public static ConfigEntry<int> traderRepairCost; private static ConfigEntry<string> tradersToRepairWeapons; private static ConfigEntry<string> tradersToRepairArmor; public static ConfigEntry<bool> traderUseCoins; public static ConfigEntry<bool> traderUseFlexiblePricing; public static ConfigEntry<int> traderCoinsMinimumAmount; public static ConfigEntry<int> traderCoinsIncreaseAmount; public static ConfigEntry<int> traderCoinsDecreaseAmount; public static ConfigEntry<int> traderCoinsMaximumAmount; public static ConfigEntry<float> traderDiscount; public static ConfigEntry<float> traderMarkup; public static ConfigEntry<int> traderCoinsReplenishmentRate; public static ConfigEntry<bool> traderCoinsSendReplenishmentMessage; public static ConfigEntry<bool> coinsPatch; public static ConfigEntry<float> coinsWeight; public static ConfigEntry<int> coinsStackSize; public static ConfigEntry<string> tradersCustomPrefabs; public static ConfigEntry<bool> disableVanillaItems; public static ConfigEntry<float> qualityMultiplier; public static ConfigEntry<bool> hideEquippedAndHotbarItems; public static ConfigEntry<bool> addCommonValuableItemsToSellList; public static ConfigEntry<Vector2> fixedStoreGuiPosition; public static ConfigEntry<bool> enableBuyBack; public static ConfigEntry<Color> colorBuybackNormal; public static ConfigEntry<Color> colorBuybackHighlighted; public static ConfigEntry<Color> colorBuybackText; public static readonly Dictionary<string, List<TradeableItem>> tradeableItems = new Dictionary<string, List<TradeableItem>>(); public static readonly Dictionary<string, List<TradeableItem>> sellableItems = new Dictionary<string, List<TradeableItem>>(); private static readonly CustomSyncedValue<Dictionary<string, string>> configsJSON = new CustomSyncedValue<Dictionary<string, string>>(configSync, "JSON configs", new Dictionary<string, string>()); private static DirectoryInfo pluginDirectory; private static DirectoryInfo configDirectory; public static Component epicLootPlugin; public static HashSet<string> _ignoreItemDiscovery = new HashSet<string>(); public static HashSet<string> _tradersToRepairWeapons = new HashSet<string>(); public static HashSet<string> _tradersToRepairArmor = new HashSet<string>(); private void Awake() { harmony.PatchAll(); instance = this; logger = ((BaseUnityPlugin)this).Logger; pluginDirectory = new DirectoryInfo(Assembly.GetExecutingAssembly().Location).Parent; configDirectory = new DirectoryInfo(Paths.ConfigPath); ConfigInit(); configSync.AddLockingConfigEntry<bool>(configLocked); configsJSON.ValueChanged += StartConfigLoad; epicLootPlugin = ((Component)this).GetComponent("EpicLoot"); Game.isModded = true; } private void Update() { AmountDialog.Update(); } private void OnDestroy() { ((BaseUnityPlugin)this).Config.Save(); instance = null; Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } public static void LogInfo(object data) { if (loggingEnabled.Value) { ((BaseUnityPlugin)instance).Logger.LogInfo(data); } } private void ConfigInit() { //IL_03ca: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_04c7: Unknown result type (might be due to invalid IL or missing references) config("General", "NexusID", 2509, "Nexus mod ID for updates", synchronizedSetting: false); modEnabled = config("General", "Enabled", defaultValue: true, "Enable this mod. Reload the game to take effect."); configLocked = config("General", "Lock Configuration", defaultValue: true, "Configuration is locked and can be changed by server admins only."); loggingEnabled = config("General", "Logging enabled", defaultValue: false, "Enable logging. [Not Synced with Server]", synchronizedSetting: false); checkForDiscovery = config("Item discovery", "Sell only discovered items", defaultValue: true, "Trader will not sell items had not discovered by a buyer."); checkForDiscoveryIgnoreItems = config("Item discovery", "Undiscovered items list to sell", "", "Trader will sell items from that list without check for discovery. Vanilla items are included by default."); checkForDiscoveryIgnoreItems.SettingChanged += delegate { FillConfigLists(); }; coinsPatch = config("Item coins", "Change values", defaultValue: false, "Change properties of coins item"); coinsWeight = config("Item coins", "Coins weight", 0f, "Weight of single coin"); coinsStackSize = config("Item coins", "Coins stack size", 2000, "Max size of coins stack"); traderRepair = config("Trader repair", "Traders can repair items", defaultValue: true, "Traders will have an ability to repair items"); tradersToRepairWeapons = config("Trader repair", "Traders capable to repair weapons", "Haldor", "Prefab name of Traders that have an ability to repair weapons"); tradersToRepairArmor = config("Trader repair", "Traders capable to repair armor", "Hildir", "Prefab name of Traders that have an ability to repair armor"); traderRepairCost = config("Trader repair", "Traders repair cost", 2, "Cost of repair in gold"); tradersToRepairWeapons.SettingChanged += delegate { FillConfigLists(); }; tradersToRepairArmor.SettingChanged += delegate { FillConfigLists(); }; traderUseCoins = config("Trader coins", "Traders use coins", defaultValue: true, "Traders will have an limited daily refilled amount of coins"); traderUseFlexiblePricing = config("Trader coins", "Traders use flexible pricing", defaultValue: true, "Traders will give a discount when their amount of coins is more than minimum or will set a markup when their amount of coins is less than minimum. Amount changes gradually."); traderCoinsMinimumAmount = config("Trader coins pricing", "Amount of coins after replenishment minimum", 2000, "Minimum amount of coins trader will have after replenishment."); traderCoinsIncreaseAmount = config("Trader coins pricing", "Amount of coins replenished daily", 1000, "Amount of coins added to current amount until maximum is reached"); traderCoinsDecreaseAmount = config("Trader coins pricing", "Amount of coins removed daily", 0, "Amount of coins removed from current amount until maximum is reached"); traderCoinsMaximumAmount = config("Trader coins pricing", "Amount of coins after replenishment maximum", 6000, "Maximum amount of coins for replenishments to stop."); traderDiscount = config("Trader coins pricing", "Trader discount", 0.7f, "Discount for items to buy from trader when current amount of coins is more than maximum replenishment amount."); traderMarkup = config("Trader coins pricing", "Trader markup", 1.5f, "Markup for items to buy from trader when current amount of coins is less than minimum replenishment amount."); traderCoinsReplenishmentRate = config("Trader coins pricing", "Trader coins replenishment rate in days", 1, "Amount of coins is updated at morning"); traderCoinsSendReplenishmentMessage = config("Trader coins pricing", "Send replenishment message in the morning", defaultValue: true, "Show message when trader coins are updated"); tradersCustomPrefabs = config("Misc", "Custom traders prefab names", "", "List of custom prefab names of Trader added by mods to control coins. Prefab name, case sensitive, comma separated"); disableVanillaItems = config("Misc", "Disable vanilla items", defaultValue: false, "Disable vanilla items on traders. Custom traders could or could not work depending on their implementation."); qualityMultiplier = config("Misc", "Quality multiplier", 0f, "Quality multiplier for price. Each level of additional quality level adds that percent of price."); hideEquippedAndHotbarItems = config("Misc", "Hide equipped and hotbar items", defaultValue: true, "Equippable items from first row of inventory and all items currently equipped will not be shown at the sell list."); addCommonValuableItemsToSellList = config("Misc", "Add common valuable items to sell list", defaultValue: true, "Add common valuable items to all traders sell list."); fixedStoreGuiPosition = config<Vector2>("Misc", "Fixed position for Store GUI", Vector2.zero, "If set then Store GUI will take that absolute position."); addCommonValuableItemsToSellList.SettingChanged += delegate { StartConfigLoad(); }; fixedStoreGuiPosition.SettingChanged += delegate { StorePanel.SetStoreGuiPosition(); }; enableBuyBack = config("Trader buyback", "Enable buyback for last item sold", defaultValue: true, "First item to buy will be the last item you have recently sold."); colorBuybackNormal = config<Color>("Trader buyback", "Item background color", new Color(0f, 0.42f, 0.42f), "Color of buyback item background."); colorBuybackHighlighted = config<Color>("Trader buyback", "Item highlighted color", new Color(0.25f, 0.62f, 0.62f), "Color of highlighted buyback item."); colorBuybackText = config<Color>("Trader buyback", "Item font color", new Color(1f, 0.81f, 0f), "Color of buyback item name."); InitCommands(); } private ConfigEntry<T> config<T>(string group, string name, T defaultValue, ConfigDescription description, bool synchronizedSetting = true) { ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(group, name, defaultValue, description); SyncedConfigEntry<T> syncedConfigEntry = configSync.AddConfigEntry<T>(val); syncedConfigEntry.SynchronizedConfig = synchronizedSetting; return val; } private ConfigEntry<T> config<T>(string group, string name, T defaultValue, string description, bool synchronizedSetting = true) { //IL_000c: Unknown result type (might be due to invalid IL or mi