Decompiled source of MerchantNPCs v0.0.4

MerchantNPCs.dll

Decompiled a week ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using MerchantNPCs.MerchantTrading;
using Microsoft.CodeAnalysis;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
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: IgnoresAccessChecksTo("YamlDotNet")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("MerchantNPCs")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A mod that adds buildable merchant NPCs to Valheim")]
[assembly: AssemblyFileVersion("0.0.3.0")]
[assembly: AssemblyInformationalVersion("0.0.3")]
[assembly: AssemblyProduct("MerchantNPCs")]
[assembly: AssemblyTitle("MerchantNPCs")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.0.3.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace MerchantNPCs
{
	[BepInPlugin("ruijven.merchantnpcs", "MerchantNPCs", "0.0.4")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	internal class MerchantNPCsPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "ruijven.merchantnpcs";

		public const string PluginName = "MerchantNPCs";

		public const string PluginVersion = "0.0.4";

		internal static ManualLogSource Logger;

		private const string AssetBundleName = "merchant1_ru";

		private AssetBundle _merchantAssetBundle;

		private MerchantPieces _merchantPieces;

		private ConfigEntry<bool> _isModEnabled;

		internal static MerchantNPCsPlugin Instance { get; private set; }

		public Dictionary<string, MerchantCostConfig> MerchantCosts { get; private set; } = new Dictionary<string, MerchantCostConfig>();


		private void ExtractEmbeddedConfigs()
		{
			try
			{
				string[] manifestResourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames();
				Logger.LogInfo((object)$"Found {manifestResourceNames.Length} embedded resources:");
				string[] array = manifestResourceNames;
				foreach (string text in array)
				{
					Logger.LogInfo((object)("  - " + text));
				}
				string text2 = Path.Combine(Paths.ConfigPath, "MerchantNPCs");
				if (!Directory.Exists(text2))
				{
					Directory.CreateDirectory(text2);
					Logger.LogInfo((object)("Created config directory: " + text2));
				}
				string[] array2 = new string[9] { "Meadows.txt", "BlackForest.txt", "Swamp.txt", "Mountains.txt", "Plains.txt", "Mistlands.txt", "Ashlands.txt", "DeepNorth.txt", "Extra.txt" };
				string[] array3 = array2;
				foreach (string text3 in array3)
				{
					string[] array4 = new string[3]
					{
						"MerchantNPCs.Configs." + text3,
						"Configs." + text3,
						text3
					};
					string text4 = Path.Combine(text2, text3);
					bool flag = false;
					if (!File.Exists(text4))
					{
						string[] array5 = array4;
						foreach (string text5 in array5)
						{
							using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text5);
							if (stream != null)
							{
								using (FileStream destination = new FileStream(text4, FileMode.Create))
								{
									stream.CopyTo(destination);
								}
								Logger.LogInfo((object)("Extracted config file: " + text3 + " from resource " + text5));
								flag = true;
								break;
							}
						}
						if (!flag)
						{
							string text6 = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "..\\..\\..\\Configs", text3);
							if (File.Exists(text6))
							{
								File.Copy(text6, text4);
								Logger.LogInfo((object)("Copied config file from project directory: " + text3));
							}
							else
							{
								Logger.LogWarning((object)("Could not find config file " + text3 + " as embedded resource or in project directory"));
								File.WriteAllText(text4, "# " + text3.Replace(".txt", "") + " Merchant Items\n# Format: item:price\n\n# Add your items here\n");
								Logger.LogInfo((object)("Created empty config file: " + text3));
							}
						}
					}
					else
					{
						Logger.LogDebug((object)("Config file already exists: " + text3));
					}
				}
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error extracting config files: " + ex.Message));
			}
		}

		private void Awake()
		{
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			Instance = this;
			Logger = ((BaseUnityPlugin)this).Logger;
			_isModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsModEnabled", true, "Enables or disables the mod");
			if (!_isModEnabled.Value)
			{
				Logger.LogInfo((object)"Mod is disabled via configuration");
				return;
			}
			InitializeMerchantCostConfigs();
			ExtractEmbeddedConfigs();
			PrefabManager.OnVanillaPrefabsAvailable += AddMerchantPieces;
			ZoneManager.OnVanillaLocationsAvailable += InitializeMerchantTrading;
			Harmony val = new Harmony("ruijven.merchantnpcs");
			val.PatchAll(Assembly.GetExecutingAssembly());
			Logger.LogInfo((object)"MerchantNPCs v0.0.4 loaded successfully!");
		}

		private void InitializeMerchantCostConfigs()
		{
			Logger.LogInfo((object)"Initializing merchant cost configurations");
			MerchantCostConfig merchantCostConfig = new MerchantCostConfig();
			merchantCostConfig.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Meadows Merchant", 1, "Wood", 50);
			merchantCostConfig.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Meadows Merchant", 2, "Stone", 50);
			merchantCostConfig.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Meadows Merchant", 3, "Flint", 25);
			MerchantCosts["Meadows"] = merchantCostConfig;
			MerchantCostConfig merchantCostConfig2 = new MerchantCostConfig();
			merchantCostConfig2.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Black Forest Merchant", 1, "RoundLog", 20);
			merchantCostConfig2.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Black Forest Merchant", 2, "TrollHide", 10);
			merchantCostConfig2.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Black Forest Merchant", 3, "Copper", 10);
			merchantCostConfig2.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Black Forest Merchant", 4, "TrophyEikthyr", 1);
			MerchantCosts["BlackForest"] = merchantCostConfig2;
			MerchantCostConfig merchantCostConfig3 = new MerchantCostConfig();
			merchantCostConfig3.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Swamp Merchant", 1, "ElderBark", 20);
			merchantCostConfig3.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Swamp Merchant", 2, "Guck", 10);
			merchantCostConfig3.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Swamp Merchant", 3, "Iron", 10);
			merchantCostConfig3.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Swamp Merchant", 4, "TrophyTheElder", 1);
			MerchantCosts["Swamp"] = merchantCostConfig3;
			MerchantCostConfig merchantCostConfig4 = new MerchantCostConfig();
			merchantCostConfig4.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Mountains Merchant", 1, "FreezeGland", 10);
			merchantCostConfig4.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Mountains Merchant", 2, "WolfPelt", 10);
			merchantCostConfig4.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Mountains Merchant", 3, "Silver", 10);
			merchantCostConfig4.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Mountains Merchant", 4, "TrophyBonemass", 1);
			MerchantCosts["Mountain"] = merchantCostConfig4;
			MerchantCostConfig merchantCostConfig5 = new MerchantCostConfig();
			merchantCostConfig5.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Plains Merchant", 1, "Barley", 10);
			merchantCostConfig5.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Plains Merchant", 2, "BlackMetalScrap", 10);
			merchantCostConfig5.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Plains Merchant", 3, "Needle", 5);
			merchantCostConfig5.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Plains Merchant", 4, "TrophyDragonQueen", 1);
			MerchantCosts["Plains"] = merchantCostConfig5;
			MerchantCostConfig merchantCostConfig6 = new MerchantCostConfig();
			merchantCostConfig6.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Mistlands Merchant", 1, "RoyalJelly", 10);
			merchantCostConfig6.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Mistlands Merchant", 2, "YggdrasilWood", 20);
			merchantCostConfig6.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Mistlands Merchant", 3, "Carapace", 5);
			merchantCostConfig6.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Mistlands Merchant", 4, "TrophyGoblinKing", 1);
			MerchantCosts["Mistlands"] = merchantCostConfig6;
			MerchantCostConfig merchantCostConfig7 = new MerchantCostConfig();
			merchantCostConfig7.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Ashlands Merchant", 1, "Blackwood", 20);
			merchantCostConfig7.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Ashlands Merchant", 2, "FlametalOreNew", 5);
			merchantCostConfig7.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Ashlands Merchant", 3, "Fiddleheadfern", 10);
			merchantCostConfig7.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Ashlands Merchant", 4, "TrophySeekerQueen", 1);
			MerchantCosts["Ashlands"] = merchantCostConfig7;
			MerchantCostConfig merchantCostConfig8 = new MerchantCostConfig();
			merchantCostConfig8.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Deep North Merchant", 1, "FreezeGland", 200);
			merchantCostConfig8.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Deep North Merchant", 2, "WolfPelt", 200);
			merchantCostConfig8.AddResourceRequirement(((BaseUnityPlugin)this).Config, "Deep North Merchant", 3, "TrophyGoblinKing", 20);
			MerchantCosts["DeepNorth"] = merchantCostConfig8;
			Logger.LogInfo((object)$"Initialized {MerchantCosts.Count} merchant cost configurations");
		}

		private void AddMerchantPieces()
		{
			try
			{
				LoadAssetBundle();
				if ((Object)(object)_merchantAssetBundle == (Object)null)
				{
					Logger.LogError((object)"Failed to load asset bundle");
					return;
				}
				RegisterAllAssets();
				CreateMerchantPieceTab();
				_merchantPieces = new MerchantPieces(_merchantAssetBundle, this);
				_merchantPieces.AddAllPieces();
				Logger.LogInfo((object)"Merchant pieces added successfully");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error adding merchant pieces: " + ex.Message + "\n" + ex.StackTrace));
			}
		}

		private void LoadAssetBundle()
		{
			try
			{
				_merchantAssetBundle = AssetUtils.LoadAssetBundleFromResources("merchant1_ru", Assembly.GetExecutingAssembly());
				if ((Object)(object)_merchantAssetBundle != (Object)null)
				{
					string[] allAssetNames = _merchantAssetBundle.GetAllAssetNames();
					Logger.LogInfo((object)$"Asset bundle contains {allAssetNames.Length} assets:");
					string[] array = allAssetNames;
					foreach (string text in array)
					{
						Logger.LogInfo((object)("- " + text));
					}
					Logger.LogInfo((object)"Asset bundle contains the following asset types:");
					string[] array2 = (from name in _merchantAssetBundle.GetAllAssetNames()
						where (Object)(object)_merchantAssetBundle.LoadAsset<GameObject>(name) != (Object)null
						select name).ToArray();
					Logger.LogInfo((object)string.Format("GameObjects ({0}): {1}", array2.Length, string.Join(", ", array2)));
					string[] array3 = (from name in _merchantAssetBundle.GetAllAssetNames()
						where (Object)(object)_merchantAssetBundle.LoadAsset<Sprite>(name) != (Object)null
						select name).ToArray();
					Logger.LogInfo((object)string.Format("Sprites ({0}): {1}", array3.Length, string.Join(", ", array3)));
					string[] array4 = (from name in _merchantAssetBundle.GetAllAssetNames()
						where (Object)(object)_merchantAssetBundle.LoadAsset<Material>(name) != (Object)null
						select name).ToArray();
					Logger.LogInfo((object)string.Format("Materials ({0}): {1}", array4.Length, string.Join(", ", array4)));
					string[] array5 = (from name in _merchantAssetBundle.GetAllAssetNames()
						where (Object)(object)_merchantAssetBundle.LoadAsset<Texture>(name) != (Object)null
						select name).ToArray();
					Logger.LogInfo((object)string.Format("Textures ({0}): {1}", array5.Length, string.Join(", ", array5)));
					string[] array6 = (from name in _merchantAssetBundle.GetAllAssetNames()
						where (Object)(object)_merchantAssetBundle.LoadAsset<AnimationClip>(name) != (Object)null
						select name).ToArray();
					Logger.LogInfo((object)string.Format("Animations ({0}): {1}", array6.Length, string.Join(", ", array6)));
					Logger.LogInfo((object)"Asset bundle loaded successfully");
				}
				else
				{
					Logger.LogError((object)"Asset bundle is null after loading");
				}
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error loading asset bundle: " + ex.Message + "\n" + ex.StackTrace));
			}
		}

		private void CreateMerchantPieceTab()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Expected O, but got Unknown
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Sprite val = null;
				if ((Object)(object)_merchantAssetBundle != (Object)null)
				{
					val = _merchantAssetBundle.LoadAsset<Sprite>("tradericon_ru");
					if ((Object)(object)val == (Object)null)
					{
						Logger.LogWarning((object)"Could not load tradericon_ru from asset bundle, using default tab icon");
					}
				}
				PieceTableConfig val2 = new PieceTableConfig();
				val2.CanRemovePieces = true;
				val2.UseCategories = true;
				val2.UseCustomCategories = true;
				val2.CustomCategories = new string[1] { "Merchants" };
				PieceTableConfig val3 = val2;
				CustomPieceTable val4 = new CustomPieceTable("_MerchantPieceTable", val3);
				PieceManager.Instance.AddPieceTable(val4);
				PieceManager.Instance.AddPieceCategory("Merchants");
				Logger.LogInfo((object)"Created merchant piece table with name: _MerchantPieceTable");
				Logger.LogInfo((object)"Added custom category 'Merchants' to the Hammer");
				Logger.LogInfo((object)"Merchant piece tab created successfully");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)("Error creating merchant piece tab: " + ex.Message + "\n" + ex.StackTrace));
			}
		}

		private void RegisterAllAssets()
		{
			try
			{
				if ((Object)(object)_merchantAssetBundle == (Object)null)
				{
					Logger.LogError((object)"Cannot register assets: Asset bundle is null");
					return;
				}
				string[] allAssetNames = _merchantAssetBundle.GetAllAssetNames();
				Logger.LogInfo((object)$"Preparing to register {allAssetNames.Length} assets from bundle");
				int num = 0;
				string[] array = allAssetNames;
				foreach (string path in array)
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
					GameObject val = _merchantAssetBundle.LoadAsset<GameObject>(fileNameWithoutExtension);
					if ((Object)(object)val != (Object)null)
					{
						try
						{
							PrefabManager.Instance.AddPrefab(val);
							Logger.LogInfo((object)("Registered prefab: " + fileNameWithoutExtension));
							num++;
						}
						catch (Exception ex)
						{
							Logger.LogWarning((object)("Failed to register prefab " + fileNameWithoutExtension + ": " + ex.Message));
						}
					}
				}
				Logger.LogInfo((object)$"Registered {num} prefabs");
				int num2 = 0;
				string[] array2 = allAssetNames;
				foreach (string path2 in array2)
				{
					string fileNameWithoutExtension2 = Path.GetFileNameWithoutExtension(path2);
					Sprite val2 = _merchantAssetBundle.LoadAsset<Sprite>(fileNameWithoutExtension2);
					if ((Object)(object)val2 != (Object)null)
					{
						Logger.LogInfo((object)("Loaded sprite: " + fileNameWithoutExtension2));
						num2++;
					}
				}
				Logger.LogInfo((object)$"Loaded {num2} sprites");
				int num3 = 0;
				string[] array3 = allAssetNames;
				foreach (string path3 in array3)
				{
					string fileNameWithoutExtension3 = Path.GetFileNameWithoutExtension(path3);
					Material val3 = _merchantAssetBundle.LoadAsset<Material>(fileNameWithoutExtension3);
					if ((Object)(object)val3 != (Object)null)
					{
						Logger.LogInfo((object)("Loaded material: " + fileNameWithoutExtension3));
						num3++;
					}
				}
				Logger.LogInfo((object)$"Loaded {num3} materials");
				int num4 = 0;
				string[] array4 = allAssetNames;
				foreach (string path4 in array4)
				{
					string fileNameWithoutExtension4 = Path.GetFileNameWithoutExtension(path4);
					Texture val4 = _merchantAssetBundle.LoadAsset<Texture>(fileNameWithoutExtension4);
					if ((Object)(object)val4 != (Object)null)
					{
						Logger.LogInfo((object)("Loaded texture: " + fileNameWithoutExtension4));
						num4++;
					}
				}
				Logger.LogInfo((object)$"Loaded {num4} textures");
				int num5 = 0;
				string[] array5 = allAssetNames;
				foreach (string path5 in array5)
				{
					string fileNameWithoutExtension5 = Path.GetFileNameWithoutExtension(path5);
					AnimationClip val5 = _merchantAssetBundle.LoadAsset<AnimationClip>(fileNameWithoutExtension5);
					if ((Object)(object)val5 != (Object)null)
					{
						Logger.LogInfo((object)("Loaded animation: " + fileNameWithoutExtension5));
						num5++;
					}
				}
				Logger.LogInfo((object)$"Loaded {num5} animations");
				Logger.LogInfo((object)"All assets registered successfully");
			}
			catch (Exception ex2)
			{
				Logger.LogError((object)("Error registering assets: " + ex2.Message + "\n" + ex2.StackTrace));
			}
		}

		private void InitializeMerchantTrading()
		{
			try
			{
				if (MerchantManager.Instance != null)
				{
					MerchantManager.Instance.Initialize();
					Logger.LogInfo((object)"Merchant manager initialized successfully");
				}
				else
				{
					Logger.LogError((object)"MerchantManager instance is null");
				}
				try
				{
					MerchantUI.Initialize();
					Logger.LogInfo((object)"MerchantUI instance initialized - UI will be created on demand");
				}
				catch (Exception ex)
				{
					Logger.LogError((object)("Error initializing merchant UI instance: " + ex.Message + "\n" + ex.StackTrace));
					Logger.LogInfo((object)"MerchantUI instance initialization failed, but the mod will continue to function");
				}
				Logger.LogInfo((object)"Merchant trading system initialized successfully");
			}
			catch (Exception ex2)
			{
				Logger.LogError((object)("Error initializing merchant trading system: " + ex2.Message + "\n" + ex2.StackTrace));
			}
		}
	}
	public class MerchantBehavior : MonoBehaviour, Hoverable, Interactable
	{
		[Header("Merchant Settings")]
		[SerializeField]
		private string _merchantName = "Merchant";

		[SerializeField]
		private string _merchantType = "";

		[SerializeField]
		private string _merchantGreeting = "Hello, traveler!";

		[SerializeField]
		private float _interactionDistance = 5f;

		private Player _interactingPlayer;

		private string _hoverText;

		private void Awake()
		{
			if (string.IsNullOrEmpty(_merchantName) || _merchantName == "Merchant")
			{
				if (((Object)((Component)this).gameObject).name.Contains("Merch_ru"))
				{
					string name = ((Object)((Component)this).gameObject).name;
					name = name.Replace("(Clone)", "");
					string text = name.Replace("Merch_ru", "");
					if (text == "Blackforest")
					{
						_merchantName = "Black Forest Merchant";
						_merchantType = "BlackForest";
					}
					else if (text == "DeepNorth")
					{
						_merchantName = "Deep North Merchant";
						_merchantType = "DeepNorth";
					}
					else
					{
						_merchantName = text + " Merchant";
						_merchantType = text;
					}
					MerchantNPCsPlugin.Logger.LogInfo((object)("Set merchant name to " + _merchantName + " based on prefab " + name));
				}
				else
				{
					_merchantName = "Merchant";
					_merchantType = "";
					MerchantNPCsPlugin.Logger.LogWarning((object)("Could not determine merchant type from prefab name: " + ((Object)((Component)this).gameObject).name));
				}
			}
			_hoverText = "[<color=yellow><b>E</b></color>] Trade with " + _merchantName;
			if (!Object.op_Implicit((Object)(object)((Component)this).GetComponent<ZNetView>()))
			{
				MerchantNPCsPlugin.Logger.LogWarning((object)("Merchant " + ((Object)((Component)this).gameObject).name + " is missing ZNetView component"));
			}
		}

		public string GetHoverText()
		{
			return _hoverText;
		}

		public string GetHoverName()
		{
			return _merchantName;
		}

		public bool Interact(Humanoid user, bool hold, bool alt)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			MerchantNPCsPlugin.Logger.LogInfo((object)("Merchant " + ((Object)((Component)this).gameObject).name + " interaction started"));
			if (hold)
			{
				MerchantNPCsPlugin.Logger.LogInfo((object)"Hold interaction not supported");
				return false;
			}
			Player val = (Player)(object)((user is Player) ? user : null);
			if ((Object)(object)val == (Object)null)
			{
				MerchantNPCsPlugin.Logger.LogError((object)"User is not a Player");
				return false;
			}
			MerchantNPCsPlugin.Logger.LogInfo((object)("Player " + val.GetPlayerName() + " is interacting with merchant " + _merchantName));
			float num = Vector3.Distance(((Component)val).transform.position, ((Component)this).transform.position);
			MerchantNPCsPlugin.Logger.LogInfo((object)$"Distance to player: {num}, Interaction distance: {_interactionDistance}");
			if (num > _interactionDistance)
			{
				MerchantNPCsPlugin.Logger.LogInfo((object)"Player is too far away");
				((Character)val).Message((MessageType)2, "Get closer to interact with the merchant", 0, (Sprite)null);
				return false;
			}
			_interactingPlayer = val;
			MerchantNPCsPlugin.Logger.LogInfo((object)"Set interacting player");
			((Character)val).Message((MessageType)2, _merchantName + ": " + _merchantGreeting, 0, (Sprite)null);
			MerchantNPCsPlugin.Logger.LogInfo((object)("Showed greeting: " + _merchantName + ": " + _merchantGreeting));
			MerchantNPCsPlugin.Logger.LogInfo((object)"Opening merchant UI...");
			OpenMerchantUI();
			return true;
		}

		public bool UseItem(Humanoid user, ItemData item)
		{
			return false;
		}

		private void OpenMerchantUI()
		{
			try
			{
				MerchantNPCsPlugin.Logger.LogInfo((object)"OpenMerchantUI method called");
				if ((Object)(object)_interactingPlayer == (Object)null)
				{
					MerchantNPCsPlugin.Logger.LogError((object)"Cannot open merchant UI: No interacting player");
					return;
				}
				MerchantNPCsPlugin.Logger.LogInfo((object)("Interacting player: " + _interactingPlayer.GetPlayerName()));
				MerchantNPCsPlugin.Logger.LogInfo((object)("Merchant type: " + _merchantType));
				if ((Object)(object)MerchantUI.Instance == (Object)null)
				{
					MerchantNPCsPlugin.Logger.LogInfo((object)"MerchantUI instance is null, initializing...");
					MerchantUI.Initialize();
					if ((Object)(object)MerchantUI.Instance == (Object)null)
					{
						MerchantNPCsPlugin.Logger.LogError((object)"Failed to initialize MerchantUI instance");
						((Character)_interactingPlayer).Message((MessageType)2, "Error initializing merchant UI", 0, (Sprite)null);
						return;
					}
					MerchantNPCsPlugin.Logger.LogInfo((object)"MerchantUI instance initialized successfully");
				}
				else
				{
					MerchantNPCsPlugin.Logger.LogInfo((object)"MerchantUI instance already exists");
				}
				MerchantNPCsPlugin.Logger.LogInfo((object)"Calling MerchantUI.Show method...");
				MerchantUI.Instance.Show(_merchantType, _interactingPlayer);
				MerchantNPCsPlugin.Logger.LogInfo((object)"MerchantUI.Show method completed");
			}
			catch (Exception ex)
			{
				MerchantNPCsPlugin.Logger.LogError((object)("Error opening merchant UI: " + ex.Message + "\n" + ex.StackTrace));
				if ((Object)(object)_interactingPlayer != (Object)null)
				{
					((Character)_interactingPlayer).Message((MessageType)2, "Error opening merchant UI", 0, (Sprite)null);
				}
			}
		}
	}
	public class ResourceRequirement
	{
		public ConfigEntry<string> ItemType { get; set; }

		public ConfigEntry<int> Amount { get; set; }
	}
	public class MerchantCostConfig
	{
		private List<ResourceRequirement> _requirements = new List<ResourceRequirement>();

		public void AddResourceRequirement(ConfigFile config, string merchantType, int index, string defaultItemType, int defaultAmount)
		{
			ResourceRequirement item = new ResourceRequirement
			{
				ItemType = config.Bind<string>(merchantType, $"Resource{index}Type", defaultItemType, $"Item type for resource requirement #{index}"),
				Amount = config.Bind<int>(merchantType, $"Resource{index}Amount", defaultAmount, $"Amount required for resource #{index} ({defaultItemType})")
			};
			_requirements.Add(item);
		}

		public List<(string itemType, int amount)> GetRequirements()
		{
			List<(string, int)> list = new List<(string, int)>();
			foreach (ResourceRequirement requirement in _requirements)
			{
				if (!string.IsNullOrEmpty(requirement.ItemType.Value) && requirement.Amount.Value > 0)
				{
					list.Add((requirement.ItemType.Value, requirement.Amount.Value));
				}
			}
			return list;
		}
	}
	internal class MerchantPieces
	{
		private readonly AssetBundle _assetBundle;

		private readonly MerchantNPCsPlugin _plugin;

		private readonly List<CustomPiece> _addedPieces = new List<CustomPiece>();

		public MerchantPieces(AssetBundle assetBundle, MerchantNPCsPlugin plugin)
		{
			_assetBundle = assetBundle;
			_plugin = plugin;
		}

		public void AddAllPieces()
		{
			try
			{
				if ((Object)(object)_assetBundle == (Object)null)
				{
					MerchantNPCsPlugin.Logger.LogError((object)"Asset bundle is null, cannot add pieces");
					return;
				}
				AddMeadowsMerchant();
				AddBlackForestMerchant();
				AddSwampMerchant();
				AddMountainMerchant();
				AddPlainsMerchant();
				AddMistlandsMerchant();
				AddAshlandsMerchant();
				AddDeepNorthMerchant();
				MerchantNPCsPlugin.Logger.LogInfo((object)$"Added {_addedPieces.Count} merchant pieces to the game");
			}
			catch (Exception ex)
			{
				MerchantNPCsPlugin.Logger.LogError((object)("Error adding merchant pieces: " + ex.Message + "\n" + ex.StackTrace));
			}
		}

		private void AddMerchantPiece(string prefabName, string pieceName, string description, List<RequirementConfig> requirements)
		{
			//IL_0105: Unknown result type (might be due to invalid IL or missing references)
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_011a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Expected O, but got Unknown
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0155: Expected O, but got Unknown
			try
			{
				GameObject val = _assetBundle.LoadAsset<GameObject>(prefabName);
				if ((Object)(object)val == (Object)null)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("Failed to load prefab " + prefabName + " from asset bundle"));
					return;
				}
				EnsurePieceComponents(val);
				string text = prefabName.Replace("Merch_ru", "");
				Sprite val2 = null;
				string text2 = ((!(text == "Mountain")) ? (text + "Icon_ru") : "MountainsIcon_ru");
				val2 = _assetBundle.LoadAsset<Sprite>(text2);
				MerchantNPCsPlugin.Logger.LogInfo((object)("Trying to load icon " + text2 + " for " + prefabName));
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = _assetBundle.LoadAsset<Sprite>("texts_icon1");
					MerchantNPCsPlugin.Logger.LogWarning((object)("Using fallback icon for " + prefabName));
				}
				if ((Object)(object)val2 == (Object)null)
				{
					MerchantNPCsPlugin.Logger.LogWarning((object)("Failed to load any icon for " + prefabName));
				}
				PieceConfig val3 = new PieceConfig
				{
					Name = pieceName,
					Description = description,
					PieceTable = "Hammer",
					Category = "Merchants",
					Requirements = requirements.ToArray(),
					Icon = val2
				};
				CustomPiece val4 = new CustomPiece(val, false, val3);
				PieceManager.Instance.AddPiece(val4);
				_addedPieces.Add(val4);
				MerchantNPCsPlugin.Logger.LogInfo((object)("Added merchant piece: " + pieceName));
			}
			catch (Exception ex)
			{
				MerchantNPCsPlugin.Logger.LogError((object)("Error adding merchant piece " + prefabName + ": " + ex.Message + "\n" + ex.StackTrace));
			}
		}

		private void EnsurePieceComponents(GameObject prefab)
		{
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_012f: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0249: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01db: Expected O, but got Unknown
			//IL_01e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Expected O, but got Unknown
			//IL_02e8: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				Piece val = prefab.GetComponent<Piece>();
				if ((Object)(object)val == (Object)null)
				{
					val = prefab.AddComponent<Piece>();
					MerchantNPCsPlugin.Logger.LogInfo((object)("Added Piece component to " + ((Object)prefab).name));
				}
				val.m_resources = (Requirement[])(object)new Requirement[0];
				val.m_craftingStation = null;
				val.m_enabled = true;
				val.m_category = (PieceCategory)0;
				val.m_canBeRemoved = true;
				val.m_allowedInDungeons = false;
				WearNTear val2 = prefab.GetComponent<WearNTear>();
				if ((Object)(object)val2 == (Object)null)
				{
					val2 = prefab.AddComponent<WearNTear>();
					MerchantNPCsPlugin.Logger.LogInfo((object)("Added WearNTear component to " + ((Object)prefab).name));
				}
				val2.m_noRoofWear = false;
				val2.m_noSupportWear = false;
				val2.m_supports = true;
				val2.m_materialType = (MaterialType)1;
				val2.m_health = 10000000f;
				val2.m_damages.m_blunt = (DamageModifier)0;
				val2.m_damages.m_slash = (DamageModifier)0;
				val2.m_damages.m_pierce = (DamageModifier)0;
				val2.m_damages.m_chop = (DamageModifier)0;
				val2.m_damages.m_pickaxe = (DamageModifier)0;
				val2.m_damages.m_fire = (DamageModifier)0;
				val2.m_damages.m_frost = (DamageModifier)0;
				val2.m_damages.m_lightning = (DamageModifier)0;
				val2.m_damages.m_poison = (DamageModifier)0;
				val2.m_damages.m_spirit = (DamageModifier)0;
				val.m_groundPiece = false;
				val.m_groundOnly = false;
				val.m_cultivatedGroundOnly = false;
				val.m_waterPiece = false;
				val.m_noInWater = true;
				val.m_notOnWood = false;
				val.m_notOnTiltingSurface = false;
				((StaticTarget)val).m_primaryTarget = false;
				if (val.m_resources == null || val.m_resources.Length == 0)
				{
					val.m_resources = (Requirement[])(object)new Requirement[0];
				}
				if ((Object)(object)ZNetScene.instance != (Object)null)
				{
					GameObject prefab2 = ZNetScene.instance.GetPrefab("sfx_build_hammer_stone");
					if ((Object)(object)prefab2 != (Object)null)
					{
						Piece obj = val;
						EffectList val3 = new EffectList();
						val3.m_effectPrefabs = (EffectData[])(object)new EffectData[1]
						{
							new EffectData
							{
								m_prefab = prefab2
							}
						};
						obj.m_placeEffect = val3;
					}
				}
				val.m_clipEverything = true;
				ZNetView val4 = prefab.GetComponent<ZNetView>();
				if ((Object)(object)val4 == (Object)null)
				{
					val4 = prefab.AddComponent<ZNetView>();
					MerchantNPCsPlugin.Logger.LogInfo((object)("Added ZNetView component to " + ((Object)prefab).name));
				}
				val4.m_persistent = true;
				val4.m_type = (ObjectType)0;
				val4.m_syncInitialScale = true;
				if ((Object)(object)val2 != (Object)null && !val4.m_syncInitialScale)
				{
					val4.m_syncInitialScale = true;
				}
				CapsuleCollider[] components = prefab.GetComponents<CapsuleCollider>();
				CapsuleCollider[] array = components;
				foreach (CapsuleCollider val5 in array)
				{
					if (((Collider)val5).isTrigger)
					{
						MerchantNPCsPlugin.Logger.LogInfo((object)("Found trigger collider on " + ((Object)prefab).name + ", not removing it"));
					}
				}
				CapsuleCollider val6 = prefab.AddComponent<CapsuleCollider>();
				val6.center = new Vector3(0f, 1f, 0f);
				val6.radius = 0.4f;
				val6.height = 1.8f;
				val6.direction = 1;
				((Collider)val6).isTrigger = false;
				MerchantNPCsPlugin.Logger.LogInfo((object)("Added solid capsule collider to " + ((Object)prefab).name));
				MerchantBehavior component = prefab.GetComponent<MerchantBehavior>();
				if ((Object)(object)component == (Object)null)
				{
					component = prefab.AddComponent<MerchantBehavior>();
					MerchantNPCsPlugin.Logger.LogInfo((object)("Added MerchantBehavior component to " + ((Object)prefab).name));
					string value = "";
					if (((Object)prefab).name.Contains("MeadowsMerch"))
					{
						value = "Meadows";
					}
					else if (((Object)prefab).name.Contains("BlackforestMerch"))
					{
						value = "BlackForest";
					}
					else if (((Object)prefab).name.Contains("SwampMerch"))
					{
						value = "Swamp";
					}
					else if (((Object)prefab).name.Contains("MountainMerch"))
					{
						value = "Mountain";
					}
					else if (((Object)prefab).name.Contains("PlainsMerch"))
					{
						value = "Plains";
					}
					else if (((Object)prefab).name.Contains("MistlandsMerch"))
					{
						value = "Mistlands";
					}
					else if (((Object)prefab).name.Contains("AshlandsMerch"))
					{
						value = "Ashlands";
					}
					else if (((Object)prefab).name.Contains("DeepNorthMerch"))
					{
						value = "DeepNorth";
					}
					FieldInfo field = typeof(MerchantBehavior).GetField("_merchantType", BindingFlags.Instance | BindingFlags.NonPublic);
					if (field != null)
					{
						field.SetValue(component, value);
					}
				}
			}
			catch (Exception ex)
			{
				MerchantNPCsPlugin.Logger.LogError((object)("Error ensuring piece components for " + ((Object)prefab).name + ": " + ex.Message + "\n" + ex.StackTrace));
			}
		}

		private void AddMeadowsMerchant()
		{
			List<RequirementConfig> requirementsFromConfig = GetRequirementsFromConfig("Meadows", ("$item_wood", 50), ("$item_stone", 50), ("$item_flint", 25));
			AddMerchantPiece("MeadowsMerch_ru", "Meadows Merchant", "A merchant selling basic meadows resources and tools", requirementsFromConfig);
		}

		private void AddBlackForestMerchant()
		{
			List<RequirementConfig> requirementsFromConfig = GetRequirementsFromConfig("BlackForest", ("RoundLog", 20), ("TrollHide", 10), ("Copper", 10), ("TrophyEikthyr", 1));
			AddMerchantPiece("BlackforestMerch_ru", "Black Forest Merchant", "A merchant selling Black Forest resources and bronze equipment", requirementsFromConfig);
		}

		private List<RequirementConfig> GetRequirementsFromConfig(string merchantType, params (string itemType, int defaultAmount)[] defaultRequirements)
		{
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Expected O, but got Unknown
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			MerchantCostConfig value;
			MerchantCostConfig merchantCostConfig = (_plugin.MerchantCosts.TryGetValue(merchantType, out value) ? value : null);
			List<RequirementConfig> list = new List<RequirementConfig>();
			if (merchantCostConfig != null)
			{
				List<(string, int)> requirements = merchantCostConfig.GetRequirements();
				foreach (var (item, amount) in requirements)
				{
					list.Add(new RequirementConfig
					{
						Item = item,
						Amount = amount,
						Recover = true,
						AmountPerLevel = 0
					});
				}
			}
			if (list.Count == 0)
			{
				for (int i = 0; i < defaultRequirements.Length; i++)
				{
					var (item2, amount2) = defaultRequirements[i];
					list.Add(new RequirementConfig
					{
						Item = item2,
						Amount = amount2,
						Recover = true,
						AmountPerLevel = 0
					});
				}
			}
			return list;
		}

		private void AddSwampMerchant()
		{
			List<RequirementConfig> requirementsFromConfig = GetRequirementsFromConfig("Swamp", ("$item_elderbark", 20), ("$item_guck", 10), ("$item_iron", 10), ("$item_trophy_elder", 1));
			AddMerchantPiece("SwampMerch_ru", "Swamp Merchant", "A merchant selling swamp resources and iron equipment", requirementsFromConfig);
		}

		private void AddPlainsMerchant()
		{
			List<RequirementConfig> requirementsFromConfig = GetRequirementsFromConfig("Plains", ("Barley", 10), ("BlackMetalScrap", 10), ("Needle", 5), ("TrophyDragonQueen", 1));
			AddMerchantPiece("PlainsMerch_ru", "Plains Merchant", "A merchant selling plains resources and black metal equipment", requirementsFromConfig);
		}

		private void AddMountainMerchant()
		{
			List<RequirementConfig> requirementsFromConfig = GetRequirementsFromConfig("Mountains", ("FreezeGland", 10), ("WolfPelt", 10), ("Silver", 10), ("TrophyBonemass", 1));
			AddMerchantPiece("MountainMerch_ru", "Mountains Merchant", "A merchant selling mountains resources and silver equipment", requirementsFromConfig);
		}

		private void AddMistlandsMerchant()
		{
			List<RequirementConfig> requirementsFromConfig = GetRequirementsFromConfig("Mistlands", ("RoyalJelly", 10), ("YggdrasilWood", 20), ("Carapace", 5), ("TrophyGoblinKing", 1));
			AddMerchantPiece("MistlandsMerch_ru", "Mistlands Merchant", "A merchant selling mistlands resources and carapace equipment", requirementsFromConfig);
		}

		private void AddAshlandsMerchant()
		{
			List<RequirementConfig> requirementsFromConfig = GetRequirementsFromConfig("Ashlands", ("Blackwood", 20), ("FlametalOreNew", 5), ("Fiddleheadfern", 10), ("TrophySeekerQueen", 1));
			AddMerchantPiece("AshlandsMerch_ru", "Ashlands Merchant", "A merchant selling ashlands resources and flametal equipment", requirementsFromConfig);
		}

		private void AddDeepNorthMerchant()
		{
			List<RequirementConfig> requirementsFromConfig = GetRequirementsFromConfig("DeepNorth", ("FreezeGland", 200), ("WolfPelt", 200), ("TrophyFader", 20));
			AddMerchantPiece("DeepNorthMerch_ru", "Deep North Merchant", "A merchant selling Deep North resources and frost equipment", requirementsFromConfig);
		}
	}
}
namespace MerchantNPCs.MerchantTrading
{
	public class MerchantItem
	{
		public string ItemName { get; set; }

		public string OriginalItemName { get; set; }

		public int BuyPrice { get; set; }

		public int SellPrice => BuyPrice / 2;

		public ItemData ItemData { get; set; }

		public string PrefabName { get; set; }

		public bool IsAvailable => true;
	}
	public class MerchantInventory
	{
		public string MerchantType { get; set; }

		public List<MerchantItem> Items { get; set; } = new List<MerchantItem>();

	}
	public class MerchantManager
	{
		[CompilerGenerated]
		private sealed class <UpdatePlayerEquipmentDelayed>d__15 : IEnumerator<object>, IEnumerator, IDisposable
		{
			private int <>1__state;

			private object <>2__current;

			public Player player;

			public ItemData newItem;

			public MerchantManager <>4__this;

			private Exception <ex>5__1;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <UpdatePlayerEquipmentDelayed>d__15(int <>1__state)
			{
				this.<>1__state = <>1__state;
			}

			[DebuggerHidden]
			void IDisposable.Dispose()
			{
				<ex>5__1 = null;
				<>1__state = -2;
			}

			private bool MoveNext()
			{
				switch (<>1__state)
				{
				default:
					return false;
				case 0:
					<>1__state = -1;
					<>2__current = null;
					<>1__state = 1;
					return true;
				case 1:
					<>1__state = -1;
					try
					{
						((Humanoid)player).SetupEquipment();
						if ((Object)(object)((Humanoid)player).m_visEquipment != (Object)null)
						{
							((Humanoid)player).SetupVisEquipment(((Humanoid)player).m_visEquipment, false);
						}
						else
						{
							MerchantNPCsPlugin.Logger.LogWarning((object)"Visual equipment component still null after initialization attempt");
						}
						if (Object.op_Implicit((Object)(object)((Character)player).m_nview) && ((Character)player).m_nview.IsValid())
						{
							((Humanoid)player).GetInventory().Changed();
						}
						MerchantNPCsPlugin.Logger.LogInfo((object)"Equipment update completed successfully");
					}
					catch (Exception ex)
					{
						<ex>5__1 = ex;
						MerchantNPCsPlugin.Logger.LogError((object)("Error in delayed equipment update: " + <ex>5__1.Message));
					}
					return false;
				}
			}

			bool IEnumerator.MoveNext()
			{
				//ILSpy generated this explicit interface implementation from .override directive in MoveNext
				return this.MoveNext();
			}

			[DebuggerHidden]
			void IEnumerator.Reset()
			{
				throw new NotSupportedException();
			}
		}

		private static MerchantManager _instance;

		private Dictionary<string, MerchantInventory> _merchantInventories = new Dictionary<string, MerchantInventory>();

		private string _configPath;

		public static MerchantManager Instance => _instance ?? (_instance = new MerchantManager());

		private MerchantManager()
		{
			_configPath = Path.Combine(Paths.ConfigPath, "MerchantNPCs");
			if (!Directory.Exists(_configPath))
			{
				Directory.CreateDirectory(_configPath);
				CreateDefaultConfigs();
			}
		}

		public void Initialize()
		{
			LoadAllMerchantConfigs();
			MerchantNPCsPlugin.Logger.LogInfo((object)$"Loaded {_merchantInventories.Count} merchant inventories");
		}

		private void CreateDefaultConfigs()
		{
			CreateDefaultConfig("Blacksmith", new List<MerchantItem>
			{
				new MerchantItem
				{
					ItemName = "AxeIron",
					BuyPrice = 120
				},
				new MerchantItem
				{
					ItemName = "Hammer",
					BuyPrice = 80
				},
				new MerchantItem
				{
					ItemName = "PickaxeIron",
					BuyPrice = 150
				},
				new MerchantItem
				{
					ItemName = "ArrowIron",
					BuyPrice = 8
				},
				new MerchantItem
				{
					ItemName = "SwordIron",
					BuyPrice = 200
				},
				new MerchantItem
				{
					ItemName = "SwordSilver",
					BuyPrice = 350
				},
				new MerchantItem
				{
					ItemName = "AtgeirIron",
					BuyPrice = 180
				},
				new MerchantItem
				{
					ItemName = "MaceSilver",
					BuyPrice = 300
				}
			});
			CreateDefaultConfig("Farmer", new List<MerchantItem>
			{
				new MerchantItem
				{
					ItemName = "Carrot",
					BuyPrice = 10
				},
				new MerchantItem
				{
					ItemName = "CarrotSeeds",
					BuyPrice = 5
				},
				new MerchantItem
				{
					ItemName = "Turnip",
					BuyPrice = 15
				},
				new MerchantItem
				{
					ItemName = "TurnipSeeds",
					BuyPrice = 8
				},
				new MerchantItem
				{
					ItemName = "Flax",
					BuyPrice = 25
				},
				new MerchantItem
				{
					ItemName = "Barley",
					BuyPrice = 20
				},
				new MerchantItem
				{
					ItemName = "Honey",
					BuyPrice = 12
				},
				new MerchantItem
				{
					ItemName = "QueenBee",
					BuyPrice = 200
				},
				new MerchantItem
				{
					ItemName = "Cultivator",
					BuyPrice = 60
				}
			});
			CreateDefaultConfig("Innkeeper", new List<MerchantItem>
			{
				new MerchantItem
				{
					ItemName = "MeadBaseFrostResist",
					BuyPrice = 50
				},
				new MerchantItem
				{
					ItemName = "MeadBaseHealthMedium",
					BuyPrice = 60
				},
				new MerchantItem
				{
					ItemName = "MeadBaseStaminaMedium",
					BuyPrice = 60
				},
				new MerchantItem
				{
					ItemName = "MeadBasePoisonResist",
					BuyPrice = 50
				},
				new MerchantItem
				{
					ItemName = "MeadBaseTasty",
					BuyPrice = 40
				},
				new MerchantItem
				{
					ItemName = "Bread",
					BuyPrice = 20
				},
				new MerchantItem
				{
					ItemName = "FishCooked",
					BuyPrice = 15
				},
				new MerchantItem
				{
					ItemName = "NeckTailGrilled",
					BuyPrice = 15
				},
				new MerchantItem
				{
					ItemName = "SerpentMeatCooked",
					BuyPrice = 80
				}
			});
			CreateDefaultConfig("Trader", new List<MerchantItem>
			{
				new MerchantItem
				{
					ItemName = "Ruby",
					BuyPrice = 200
				},
				new MerchantItem
				{
					ItemName = "Amber",
					BuyPrice = 100
				},
				new MerchantItem
				{
					ItemName = "FineWood",
					BuyPrice = 5
				},
				new MerchantItem
				{
					ItemName = "Iron",
					BuyPrice = 20
				},
				new MerchantItem
				{
					ItemName = "Silver",
					BuyPrice = 40
				},
				new MerchantItem
				{
					ItemName = "BlackMetal",
					BuyPrice = 60
				},
				new MerchantItem
				{
					ItemName = "Obsidian",
					BuyPrice = 25
				},
				new MerchantItem
				{
					ItemName = "Chitin",
					BuyPrice = 30
				}
			});
		}

		private void CreateDefaultConfig(string merchantType, List<MerchantItem> items)
		{
			string path = Path.Combine(_configPath, merchantType.ToLower() + ".txt");
			List<string> list = new List<string>();
			list.Add("# " + merchantType + " Items");
			list.Add("# Format: item:price");
			list.Add("");
			foreach (MerchantItem item in items)
			{
				list.Add($"{item.ItemName}:{item.BuyPrice}");
			}
			File.WriteAllLines(path, list);
			MerchantNPCsPlugin.Logger.LogInfo((object)("Created default config for " + merchantType));
		}

		public void LoadAllMerchantConfigs()
		{
			_merchantInventories.Clear();
			string[] files = Directory.GetFiles(_configPath, "*.txt");
			if (files.Length != 0)
			{
				string[] array = files;
				foreach (string text in array)
				{
					try
					{
						LoadCompactFormatConfig(text);
					}
					catch (Exception ex)
					{
						MerchantNPCsPlugin.Logger.LogError((object)("Error loading merchant config " + text + ": " + ex.Message));
					}
				}
			}
			else
			{
				string[] files2 = Directory.GetFiles(_configPath, "*.yaml");
				string[] array2 = files2;
				foreach (string text2 in array2)
				{
					try
					{
						ConvertYamlToCompactFormat(text2);
					}
					catch (Exception ex2)
					{
						MerchantNPCsPlugin.Logger.LogError((object)("Error converting YAML config " + text2 + ": " + ex2.Message));
					}
				}
				files = Directory.GetFiles(_configPath, "*.txt");
				string[] array3 = files;
				foreach (string text3 in array3)
				{
					try
					{
						LoadCompactFormatConfig(text3);
					}
					catch (Exception ex3)
					{
						MerchantNPCsPlugin.Logger.LogError((object)("Error loading merchant config " + text3 + ": " + ex3.Message));
					}
				}
			}
			PopulateItemData();
		}

		private void LoadCompactFormatConfig(string configFile)
		{
			string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(configFile);
			fileNameWithoutExtension = char.ToUpper(fileNameWithoutExtension[0]) + fileNameWithoutExtension.Substring(1);
			List<MerchantItem> list = new List<MerchantItem>();
			string[] array = File.ReadAllLines(configFile);
			string[] array2 = array;
			foreach (string text in array2)
			{
				string text2 = text.Trim();
				if (string.IsNullOrWhiteSpace(text2) || text2.StartsWith("#"))
				{
					continue;
				}
				string[] array3 = text2.Split(':');
				if (array3.Length >= 2)
				{
					string text3 = array3[0].Trim();
					string originalItemName = text3;
					if (!text3.StartsWith("$item_") && !text3.StartsWith("$"))
					{
						text3 = "$item_" + text3.Replace(" ", "_");
					}
					if (int.TryParse(array3[1].Trim(), out var result))
					{
						list.Add(new MerchantItem
						{
							ItemName = text3,
							OriginalItemName = originalItemName,
							BuyPrice = result
						});
					}
				}
			}
			MerchantInventory value = new MerchantInventory
			{
				MerchantType = fileNameWithoutExtension,
				Items = list
			};
			_merchantInventories[fileNameWithoutExtension] = value;
			MerchantNPCsPlugin.Logger.LogInfo((object)$"Loaded merchant config for {fileNameWithoutExtension} with {list.Count} items");
		}

		private void ConvertYamlToCompactFormat(string yamlFile)
		{
			try
			{
				string text = Path.ChangeExtension(yamlFile, ".txt");
				if (!File.Exists(text))
				{
					MerchantNPCsPlugin.Logger.LogWarning((object)("Could not find converted file " + text + " for " + yamlFile));
				}
			}
			catch (Exception ex)
			{
				MerchantNPCsPlugin.Logger.LogError((object)("Error converting YAML file " + yamlFile + ": " + ex.Message));
			}
		}

		private void PopulateItemData()
		{
			foreach (MerchantInventory value in _merchantInventories.Values)
			{
				foreach (MerchantItem item in value.Items)
				{
					try
					{
						GameObject val = null;
						string text = null;
						ZNetScene instance = ZNetScene.instance;
						val = ((instance != null) ? instance.GetPrefab(item.ItemName) : null);
						if ((Object)(object)val != (Object)null)
						{
							text = item.ItemName;
							MerchantNPCsPlugin.Logger.LogDebug((object)("Found prefab using prefixed item name: " + item.ItemName));
						}
						if ((Object)(object)val == (Object)null && !string.IsNullOrEmpty(item.OriginalItemName))
						{
							ZNetScene instance2 = ZNetScene.instance;
							val = ((instance2 != null) ? instance2.GetPrefab(item.OriginalItemName) : null);
							if ((Object)(object)val != (Object)null)
							{
								text = item.OriginalItemName;
								MerchantNPCsPlugin.Logger.LogDebug((object)("Found prefab using original item name: " + item.OriginalItemName));
							}
						}
						if ((Object)(object)val == (Object)null)
						{
							string text2 = item.OriginalItemName.ToLower();
							ZNetScene instance3 = ZNetScene.instance;
							val = ((instance3 != null) ? instance3.GetPrefab(text2) : null);
							if ((Object)(object)val != (Object)null)
							{
								text = text2;
								MerchantNPCsPlugin.Logger.LogDebug((object)("Found prefab using lowercase name: " + text2));
							}
						}
						if ((Object)(object)val == (Object)null)
						{
							string text3 = item.OriginalItemName.Replace(" ", "").ToLower();
							ZNetScene instance4 = ZNetScene.instance;
							val = ((instance4 != null) ? instance4.GetPrefab(text3) : null);
							if ((Object)(object)val != (Object)null)
							{
								text = text3;
								MerchantNPCsPlugin.Logger.LogDebug((object)("Found prefab using no spaces lowercase name: " + text3));
							}
						}
						if ((Object)(object)val == (Object)null)
						{
							string text4 = item.OriginalItemName.Replace(" ", "");
							if (text4.Length > 0)
							{
								text4 = char.ToUpper(text4[0]) + text4.Substring(1).ToLower();
								ZNetScene instance5 = ZNetScene.instance;
								val = ((instance5 != null) ? instance5.GetPrefab(text4) : null);
								if ((Object)(object)val != (Object)null)
								{
									text = text4;
									MerchantNPCsPlugin.Logger.LogDebug((object)("Found prefab using pascal case name: " + text4));
								}
							}
						}
						if ((Object)(object)val == (Object)null)
						{
							string[] array = item.OriginalItemName.Split(' ');
							string text5 = "";
							string[] array2 = array;
							foreach (string text6 in array2)
							{
								if (!string.IsNullOrEmpty(text6))
								{
									text5 = text5 + char.ToUpper(text6[0]) + text6.Substring(1).ToLower();
								}
							}
							ZNetScene instance6 = ZNetScene.instance;
							val = ((instance6 != null) ? instance6.GetPrefab(text5) : null);
							if ((Object)(object)val != (Object)null)
							{
								text = text5;
								MerchantNPCsPlugin.Logger.LogDebug((object)("Found prefab using multi-word pascal case name: " + text5));
							}
						}
						if ((Object)(object)val != (Object)null)
						{
							ItemDrop component = val.GetComponent<ItemDrop>();
							if ((Object)(object)component != (Object)null)
							{
								item.ItemData = component.m_itemData;
								item.PrefabName = ((Object)val).name;
								MerchantNPCsPlugin.Logger.LogDebug((object)("Found item data for " + item.ItemName + ", using prefab name: " + ((Object)val).name));
								if (component.m_itemData.m_shared.m_name != item.ItemName)
								{
									MerchantNPCsPlugin.Logger.LogDebug((object)("Item name mismatch: Config=" + item.ItemName + ", Game=" + component.m_itemData.m_shared.m_name));
								}
							}
							else
							{
								MerchantNPCsPlugin.Logger.LogWarning((object)("Prefab " + ((Object)val).name + " does not have an ItemDrop component"));
							}
						}
						else
						{
							MerchantNPCsPlugin.Logger.LogWarning((object)("Could not find prefab for item " + item.ItemName + " or " + item.OriginalItemName));
						}
					}
					catch (Exception ex)
					{
						MerchantNPCsPlugin.Logger.LogError((object)("Error populating item data for " + item.ItemName + ": " + ex.Message));
					}
				}
			}
		}

		public MerchantInventory GetMerchantInventory(string merchantType)
		{
			if (_merchantInventories.TryGetValue(merchantType, out var value))
			{
				return value;
			}
			if (merchantType == "Mountain" && !_merchantInventories.ContainsKey("Mountain") && _merchantInventories.ContainsKey("Mountains"))
			{
				MerchantNPCsPlugin.Logger.LogInfo((object)"Using Mountains inventory for Mountains Merchant");
				return _merchantInventories["Mountains"];
			}
			if (merchantType == "Mountains" && !_merchantInventories.ContainsKey("Mountains") && _merchantInventories.ContainsKey("Mountain"))
			{
				MerchantNPCsPlugin.Logger.LogInfo((object)"Using Mountain inventory for Mountains Merchant");
				return _merchantInventories["Mountain"];
			}
			return null;
		}

		public bool BuyItem(Player player, MerchantItem item, int quantity = 1)
		{
			//IL_0501: Unknown result type (might be due to invalid IL or missing references)
			//IL_0507: Expected O, but got Unknown
			try
			{
				if ((Object)(object)player == (Object)null)
				{
					MerchantNPCsPlugin.Logger.LogError((object)"BuyItem: Player is null");
					return false;
				}
				if (item == null)
				{
					MerchantNPCsPlugin.Logger.LogError((object)"BuyItem: Item is null");
					((Character)player).Message((MessageType)2, "Error: Invalid item", 0, (Sprite)null);
					return false;
				}
				if (quantity <= 0)
				{
					MerchantNPCsPlugin.Logger.LogError((object)$"BuyItem: Invalid quantity {quantity}");
					return false;
				}
				MerchantNPCsPlugin.Logger.LogInfo((object)$"Attempting to buy {quantity}x {item.ItemName}");
				if (!item.IsAvailable)
				{
					MerchantNPCsPlugin.Logger.LogInfo((object)("Item " + item.ItemName + " is not available for purchase"));
					((Character)player).Message((MessageType)2, "This item is not available for purchase", 0, (Sprite)null);
					return false;
				}
				int num = item.BuyPrice * quantity;
				MerchantNPCsPlugin.Logger.LogInfo((object)$"Total cost: {num} coins");
				if (!HasEnoughCoins(player, num))
				{
					MerchantNPCsPlugin.Logger.LogInfo((object)"Player doesn't have enough coins");
					((Character)player).Message((MessageType)2, "You don't have enough coins for that", 0, (Sprite)null);
					return false;
				}
				if (item.ItemData == null)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("BuyItem: ItemData is null for " + item.ItemName));
					((Character)player).Message((MessageType)2, "Error: Invalid item data", 0, (Sprite)null);
					return false;
				}
				if (!HasEnoughInventorySpace(player, item.ItemData, quantity))
				{
					MerchantNPCsPlugin.Logger.LogInfo((object)"Player doesn't have enough inventory space");
					((Character)player).Message((MessageType)2, "You don't have enough space for that", 0, (Sprite)null);
					return false;
				}
				MerchantNPCsPlugin.Logger.LogInfo((object)$"Removing {num} coins from player");
				RemoveCoins(player, num);
				GameObject val = null;
				if ((Object)(object)ZNetScene.instance == (Object)null)
				{
					MerchantNPCsPlugin.Logger.LogError((object)"ZNetScene.instance is null");
					((Character)player).Message((MessageType)2, "Error: Game scene not fully loaded", 0, (Sprite)null);
					return false;
				}
				try
				{
					val = ZNetScene.instance.GetPrefab(item.ItemName);
					MerchantNPCsPlugin.Logger.LogInfo((object)("Trying to get prefab by ItemName: " + item.ItemName + ", result: " + (((Object)(object)val != (Object)null) ? "found" : "not found")));
				}
				catch (Exception ex)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("Exception when getting prefab by ItemName: " + ex.Message));
				}
				if ((Object)(object)val == (Object)null && item.ItemData != null && item.ItemData.m_shared != null)
				{
					try
					{
						string name = item.ItemData.m_shared.m_name;
						MerchantNPCsPlugin.Logger.LogInfo((object)("Trying to get prefab by shared name: " + name));
						val = ZNetScene.instance.GetPrefab(name);
					}
					catch (Exception ex2)
					{
						MerchantNPCsPlugin.Logger.LogError((object)("Exception when getting prefab by shared name: " + ex2.Message));
					}
				}
				if ((Object)(object)val == (Object)null && (Object)(object)ObjectDB.instance != (Object)null)
				{
					try
					{
						val = ObjectDB.instance.GetItemPrefab(item.ItemName);
						MerchantNPCsPlugin.Logger.LogInfo((object)("Trying to get prefab from ObjectDB: " + (((Object)(object)val != (Object)null) ? "found" : "not found")));
					}
					catch (Exception ex3)
					{
						MerchantNPCsPlugin.Logger.LogError((object)("Exception when getting prefab from ObjectDB: " + ex3.Message));
					}
					if ((Object)(object)val == (Object)null && item.ItemData != null && item.ItemData.m_shared != null)
					{
						try
						{
							string name2 = item.ItemData.m_shared.m_name;
							MerchantNPCsPlugin.Logger.LogInfo((object)("Searching ObjectDB items for: " + name2));
							foreach (GameObject item2 in ObjectDB.instance.m_items)
							{
								if (!((Object)(object)item2 == (Object)null))
								{
									ItemDrop component = item2.GetComponent<ItemDrop>();
									if ((Object)(object)component != (Object)null && component.m_itemData != null && component.m_itemData.m_shared != null && component.m_itemData.m_shared.m_name == name2)
									{
										val = item2;
										MerchantNPCsPlugin.Logger.LogInfo((object)("Found prefab in ObjectDB items: " + ((Object)item2).name));
										break;
									}
								}
							}
						}
						catch (Exception ex4)
						{
							MerchantNPCsPlugin.Logger.LogError((object)("Exception when searching ObjectDB items: " + ex4.Message));
						}
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					try
					{
						MerchantNPCsPlugin.Logger.LogInfo((object)"Creating a simple prefab as last resort");
						val = new GameObject(item.ItemName);
						ItemDrop val2 = val.AddComponent<ItemDrop>();
						val2.m_itemData = item.ItemData.Clone();
					}
					catch (Exception ex5)
					{
						MerchantNPCsPlugin.Logger.LogError((object)("Exception when creating simple prefab: " + ex5.Message));
					}
				}
				if ((Object)(object)val == (Object)null)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("Could not find or create prefab for " + item.ItemName));
					((Character)player).Message((MessageType)2, "Error: Could not find item", 0, (Sprite)null);
					return false;
				}
				ItemDrop component2 = val.GetComponent<ItemDrop>();
				if ((Object)(object)component2 == (Object)null)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("Prefab " + item.ItemName + " does not have an ItemDrop component"));
					((Character)player).Message((MessageType)2, "Error: Invalid item", 0, (Sprite)null);
					return false;
				}
				try
				{
					ItemData val3 = component2.m_itemData.Clone();
					val3.m_stack = quantity;
					if (val3.m_shared == null)
					{
						MerchantNPCsPlugin.Logger.LogWarning((object)("Item " + item.ItemName + " has null m_shared, attempting to fix"));
						val3.m_shared = component2.m_itemData.m_shared;
					}
					GameObject dropPrefab = val3.m_dropPrefab;
					if (string.IsNullOrEmpty((dropPrefab != null) ? ((Object)dropPrefab).name : null))
					{
						MerchantNPCsPlugin.Logger.LogWarning((object)("Item " + item.ItemName + " has null prefab name, setting from original"));
						val3.m_dropPrefab = ((Component)component2).gameObject;
					}
					if (((Humanoid)player).GetInventory().AddItem(val3))
					{
						string name3 = item.ItemData.m_shared.m_name;
						MerchantNPCsPlugin.Logger.LogInfo((object)$"Player purchased {quantity}x {name3}");
						((Character)player).Message((MessageType)2, $"You purchased {quantity}x {name3}", 0, (Sprite)null);
						((Humanoid)player).GetInventory().Changed();
						if (val3.IsEquipable())
						{
							try
							{
								MerchantNPCsPlugin.Logger.LogInfo((object)"Updating equipment after purchase");
								if ((Object)(object)((Humanoid)player).m_visEquipment == (Object)null)
								{
									MerchantNPCsPlugin.Logger.LogWarning((object)"Player visual equipment is null, attempting to initialize");
									((Humanoid)player).m_visEquipment = ((Component)player).GetComponent<VisEquipment>();
									if ((Object)(object)((Humanoid)player).m_visEquipment == (Object)null)
									{
										((Humanoid)player).m_visEquipment = ((Component)player).gameObject.AddComponent<VisEquipment>();
									}
								}
								((Humanoid)player).GetInventory().Changed();
								((MonoBehaviour)player).StartCoroutine(UpdatePlayerEquipmentDelayed(player, val3));
								MerchantNPCsPlugin.Logger.LogInfo((object)"Equipment update initiated");
							}
							catch (Exception ex6)
							{
								MerchantNPCsPlugin.Logger.LogError((object)("Error updating equipment: " + ex6.Message));
							}
						}
						return true;
					}
					MerchantNPCsPlugin.Logger.LogError((object)("Failed to add " + item.ItemName + " to player inventory"));
					((Character)player).Message((MessageType)2, "Error: Could not add item to inventory", 0, (Sprite)null);
					return false;
				}
				catch (Exception ex7)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("Exception when adding item to inventory: " + ex7.Message));
					((Character)player).Message((MessageType)2, "Error: Failed to add item to inventory", 0, (Sprite)null);
					return false;
				}
			}
			catch (Exception ex8)
			{
				MerchantNPCsPlugin.Logger.LogError((object)("Unhandled exception in BuyItem: " + ex8.Message + "\n" + ex8.StackTrace));
				if ((Object)(object)player != (Object)null)
				{
					((Character)player).Message((MessageType)2, "Error: Failed to complete purchase", 0, (Sprite)null);
				}
				return false;
			}
		}

		[IteratorStateMachine(typeof(<UpdatePlayerEquipmentDelayed>d__15))]
		private IEnumerator UpdatePlayerEquipmentDelayed(Player player, ItemData newItem)
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <UpdatePlayerEquipmentDelayed>d__15(0)
			{
				<>4__this = this,
				player = player,
				newItem = newItem
			};
		}

		public bool SellItem(Player player, ItemData item, int quantity = 1)
		{
			if ((Object)(object)player == (Object)null || item == null || quantity <= 0 || quantity > item.m_stack)
			{
				return false;
			}
			MerchantItem merchantItem = FindMerchantItem(item.m_shared.m_name);
			if (merchantItem == null)
			{
				((Character)player).Message((MessageType)2, "This merchant doesn't buy that item", 0, (Sprite)null);
				return false;
			}
			int num = merchantItem.SellPrice * quantity;
			((Humanoid)player).GetInventory().RemoveItem(item.m_shared.m_name, quantity, -1, true);
			((Humanoid)player).GetInventory().AddItem("Coins", num, 1, 0, 0L, "0", false);
			((Character)player).Message((MessageType)2, $"You sold {quantity}x {item.m_shared.m_name} for {num} coins", 0, (Sprite)null);
			return true;
		}

		private MerchantItem FindMerchantItem(string itemName)
		{
			foreach (MerchantInventory value in _merchantInventories.Values)
			{
				foreach (MerchantItem item in value.Items)
				{
					if (item.ItemName == itemName || (item.ItemData != null && item.ItemData.m_shared.m_name == itemName))
					{
						return item;
					}
				}
			}
			return null;
		}

		private bool HasEnoughCoins(Player player, int amount)
		{
			int num = 0;
			Inventory inventory = ((Humanoid)player).GetInventory();
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem.m_shared.m_name.ToLower() == "coins" || allItem.m_shared.m_name == "$item_coins")
				{
					num += allItem.m_stack;
				}
			}
			MerchantNPCsPlugin.Logger.LogInfo((object)$"Player has {num} coins, needs {amount}");
			return num >= amount;
		}

		private void RemoveCoins(Player player, int amount)
		{
			int num = amount;
			Inventory inventory = ((Humanoid)player).GetInventory();
			List<ItemData> list = new List<ItemData>();
			foreach (ItemData allItem in inventory.GetAllItems())
			{
				if (allItem.m_shared.m_name.ToLower() == "coins" || allItem.m_shared.m_name == "$item_coins")
				{
					list.Add(allItem);
				}
			}
			foreach (ItemData item in list)
			{
				if (num <= 0)
				{
					break;
				}
				if (item.m_stack <= num)
				{
					num -= item.m_stack;
					inventory.RemoveItem(item);
					continue;
				}
				item.m_stack -= num;
				num = 0;
				break;
			}
			MerchantNPCsPlugin.Logger.LogInfo((object)$"Removed {amount} coins from player's inventory");
		}

		private bool HasEnoughInventorySpace(Player player, ItemData itemData, int quantity)
		{
			if ((Object)(object)player == (Object)null || itemData == null || quantity <= 0)
			{
				MerchantNPCsPlugin.Logger.LogError((object)"Invalid parameters in HasEnoughInventorySpace");
				return false;
			}
			if ((Object)(object)ZNetScene.instance == (Object)null)
			{
				MerchantNPCsPlugin.Logger.LogError((object)"ZNetScene.instance is null");
				return true;
			}
			if (itemData.m_shared == null)
			{
				MerchantNPCsPlugin.Logger.LogError((object)"itemData.m_shared is null");
				return true;
			}
			string name = itemData.m_shared.m_name;
			if (string.IsNullOrEmpty(name))
			{
				MerchantNPCsPlugin.Logger.LogError((object)"Item name is null or empty");
				return true;
			}
			MerchantNPCsPlugin.Logger.LogInfo((object)("Checking inventory space for item: " + name));
			GameObject val = null;
			try
			{
				val = ZNetScene.instance.GetPrefab(name);
			}
			catch (Exception ex)
			{
				MerchantNPCsPlugin.Logger.LogError((object)("Exception when getting prefab by name: " + ex.Message));
			}
			if ((Object)(object)val == (Object)null && (Object)(object)itemData.m_dropPrefab != (Object)null)
			{
				try
				{
					val = ZNetScene.instance.GetPrefab(((Object)itemData.m_dropPrefab).name);
				}
				catch (Exception ex2)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("Exception when getting prefab by dropPrefab name: " + ex2.Message));
				}
			}
			if ((Object)(object)val == (Object)null && (Object)(object)ObjectDB.instance != (Object)null)
			{
				try
				{
					val = ObjectDB.instance.GetItemPrefab(name);
				}
				catch (Exception ex3)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("Exception when getting prefab from ObjectDB: " + ex3.Message));
				}
				if ((Object)(object)val == (Object)null)
				{
					try
					{
						foreach (GameObject item in ObjectDB.instance.m_items)
						{
							if (!((Object)(object)item == (Object)null))
							{
								ItemDrop component = item.GetComponent<ItemDrop>();
								if ((Object)(object)component != (Object)null && component.m_itemData != null && component.m_itemData.m_shared != null && component.m_itemData.m_shared.m_name == name)
								{
									val = item;
									break;
								}
							}
						}
					}
					catch (Exception ex4)
					{
						MerchantNPCsPlugin.Logger.LogError((object)("Exception when searching ObjectDB items: " + ex4.Message));
					}
				}
			}
			if ((Object)(object)val == (Object)null)
			{
				MerchantNPCsPlugin.Logger.LogError((object)("Could not find prefab for " + name + " - assuming inventory has space"));
				return true;
			}
			try
			{
				bool flag = ((Humanoid)player).GetInventory().CanAddItem(val, quantity);
				MerchantNPCsPlugin.Logger.LogInfo((object)$"Can player add {quantity}x {name}? {flag}");
				return flag;
			}
			catch (Exception ex5)
			{
				MerchantNPCsPlugin.Logger.LogError((object)("Exception when checking CanAddItem: " + ex5.Message));
				return true;
			}
		}
	}
	public class MerchantUI : MonoBehaviour
	{
		private static MerchantUI _instance;

		private bool _uiCreated = false;

		private bool _needsRecreation = false;

		private GameObject _uiPanel;

		private Text _merchantNameText;

		private InputField _buySearchInput;

		private InputField _sellSearchInput;

		private RectTransform _buyItemsContainer;

		private RectTransform _sellItemsContainer;

		private Button _buyButton;

		private Button _sellButton;

		private Button _closeButton;

		private Button _quantity1Button;

		private Button _quantity5Button;

		private Button _quantity10Button;

		private Text _quantityText;

		private Player _player;

		private string _merchantType;

		private MerchantInventory _merchantInventory;

		private MerchantItem _selectedBuyItem;

		private ItemData _selectedSellItem;

		private int _currentQuantity = 1;

		private string _buySearchFilter = "";

		private string _sellSearchFilter = "";

		private GameObject _itemButtonPrefab;

		public static MerchantUI Instance => _instance;

		public static void Initialize()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			if ((Object)(object)_instance == (Object)null)
			{
				GameObject val = new GameObject("MerchantUI");
				Object.DontDestroyOnLoad((Object)(object)val);
				_instance = val.AddComponent<MerchantUI>();
				MerchantNPCsPlugin.Logger.LogInfo((object)"MerchantUI instance created - UI will be created on demand");
				SceneManager.sceneLoaded += OnSceneLoaded;
			}
		}

		private static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if ((Object)(object)_instance != (Object)null)
			{
				MerchantNPCsPlugin.Logger.LogInfo((object)("Scene loaded: " + ((Scene)(ref scene)).name + ", marking UI for recreation"));
				_instance._needsRecreation = true;
				_instance._uiCreated = false;
			}
		}

		private void OnDestroy()
		{
			MerchantNPCsPlugin.Logger.LogInfo((object)"MerchantUI OnDestroy called");
			SceneManager.sceneLoaded -= OnSceneLoaded;
			CleanupUIElements();
		}

		private void CleanupUIElements()
		{
			MerchantNPCsPlugin.Logger.LogInfo((object)"Cleaning up UI elements");
			if ((Object)(object)_uiPanel != (Object)null)
			{
				Object.Destroy((Object)(object)_uiPanel);
				_uiPanel = null;
			}
			_merchantNameText = null;
			_buySearchInput = null;
			_sellSearchInput = null;
			_buyItemsContainer = null;
			_sellItemsContainer = null;
			_buyButton = null;
			_sellButton = null;
			_closeButton = null;
			_quantity1Button = null;
			_quantity5Button = null;
			_quantity10Button = null;
			_quantityText = null;
			if ((Object)(object)_itemButtonPrefab != (Object)null)
			{
				Object.Destroy((Object)(object)_itemButtonPrefab);
				_itemButtonPrefab = null;
			}
			_uiCreated = false;
		}

		private void CreateUI()
		{
			//IL_0d5c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0d63: Expected O, but got Unknown
			//IL_15da: Unknown result type (might be due to invalid IL or missing references)
			//IL_15e1: Expected O, but got Unknown
			//IL_0540: Unknown result type (might be due to invalid IL or missing references)
			//IL_054f: Unknown result type (might be due to invalid IL or missing references)
			//IL_055e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0574: Unknown result type (might be due to invalid IL or missing references)
			//IL_057a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0658: Unknown result type (might be due to invalid IL or missing references)
			//IL_0667: Unknown result type (might be due to invalid IL or missing references)
			//IL_0676: Unknown result type (might be due to invalid IL or missing references)
			//IL_07e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_07ee: Expected O, but got Unknown
			//IL_081c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0833: Unknown result type (might be due to invalid IL or missing references)
			//IL_0840: Unknown result type (might be due to invalid IL or missing references)
			//IL_084d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0864: Unknown result type (might be due to invalid IL or missing references)
			//IL_0870: Unknown result type (might be due to invalid IL or missing references)
			//IL_08b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_08be: Expected O, but got Unknown
			//IL_08e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_08ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0916: Unknown result type (might be due to invalid IL or missing references)
			//IL_092d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0957: Unknown result type (might be due to invalid IL or missing references)
			//IL_0987: Unknown result type (might be due to invalid IL or missing references)
			//IL_098e: Expected O, but got Unknown
			//IL_09b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_09cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_09dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_09e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a41: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a48: Expected O, but got Unknown
			//IL_0a72: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a89: Unknown result type (might be due to invalid IL or missing references)
			//IL_0a96: Unknown result type (might be due to invalid IL or missing references)
			//IL_0aa3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0acb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b08: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b0f: Expected O, but got Unknown
			//IL_0b41: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b5c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b77: Unknown result type (might be due to invalid IL or missing references)
			//IL_0b92: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bad: Unknown result type (might be due to invalid IL or missing references)
			//IL_0bd8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0be2: Expected O, but got Unknown
			//IL_0c64: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c77: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c8a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0c9d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0cbf: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ccb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ed6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ee5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ef4: Unknown result type (might be due to invalid IL or missing references)
			//IL_1065: Unknown result type (might be due to invalid IL or missing references)
			//IL_106c: Expected O, but got Unknown
			//IL_109a: Unknown result type (might be due to invalid IL or missing references)
			//IL_10b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_10be: Unknown result type (might be due to invalid IL or missing references)
			//IL_10cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_10e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_10ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_1135: Unknown result type (might be due to invalid IL or missing references)
			//IL_113c: Expected O, but got Unknown
			//IL_1166: Unknown result type (might be due to invalid IL or missing references)
			//IL_117d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1194: Unknown result type (might be due to invalid IL or missing references)
			//IL_11ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_11d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_1205: Unknown result type (might be due to invalid IL or missing references)
			//IL_120c: Expected O, but got Unknown
			//IL_1236: Unknown result type (might be due to invalid IL or missing references)
			//IL_124d: Unknown result type (might be due to invalid IL or missing references)
			//IL_125a: Unknown result type (might be due to invalid IL or missing references)
			//IL_1267: Unknown result type (might be due to invalid IL or missing references)
			//IL_12bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_12c6: Expected O, but got Unknown
			//IL_12f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_1307: Unknown result type (might be due to invalid IL or missing references)
			//IL_1314: Unknown result type (might be due to invalid IL or missing references)
			//IL_1321: Unknown result type (might be due to invalid IL or missing references)
			//IL_1349: Unknown result type (might be due to invalid IL or missing references)
			//IL_1386: Unknown result type (might be due to invalid IL or missing references)
			//IL_138d: Expected O, but got Unknown
			//IL_13bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_13da: Unknown result type (might be due to invalid IL or missing references)
			//IL_13f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_1410: Unknown result type (might be due to invalid IL or missing references)
			//IL_142b: Unknown result type (might be due to invalid IL or missing references)
			//IL_1456: Unknown result type (might be due to invalid IL or missing references)
			//IL_1460: Expected O, but got Unknown
			//IL_14e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_14f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_1508: Unknown result type (might be due to invalid IL or missing references)
			//IL_151b: Unknown result type (might be due to invalid IL or missing references)
			//IL_153d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1549: Unknown result type (might be due to invalid IL or missing references)
			//IL_162a: Unknown result type (might be due to invalid IL or missing references)
			//IL_1639: Unknown result type (might be due to invalid IL or missing references)
			//IL_1648: Unknown result type (might be due to invalid IL or missing references)
			//IL_1659: Unknown result type (might be due to invalid IL or missing references)
			//IL_165f: Unknown result type (might be due to invalid IL or missing references)
			//IL_16ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_16bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_16cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_16fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_1708: Expected O, but got Unknown
			//IL_1728: Unknown result type (might be due to invalid IL or missing references)
			//IL_1737: Unknown result type (might be due to invalid IL or missing references)
			//IL_1746: Unknown result type (might be due to invalid IL or missing references)
			//IL_1779: Unknown result type (might be due to invalid IL or missing references)
			//IL_1783: Expected O, but got Unknown
			//IL_17a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_17b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_17c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_17f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_1800: Expected O, but got Unknown
			//IL_1820: Unknown result type (might be due to invalid IL or missing references)
			//IL_182f: Unknown result type (might be due to invalid IL or missing references)
			//IL_183e: Unknown result type (might be due to invalid IL or missing references)
			//IL_1873: Unknown result type (might be due to invalid IL or missing references)
			//IL_187d: Expected O, but got Unknown
			//IL_189d: Unknown result type (might be due to invalid IL or missing references)
			//IL_18ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_18bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_18f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_18fa: Expected O, but got Unknown
			//IL_191a: Unknown result type (might be due to invalid IL or missing references)
			//IL_1929: Unknown result type (might be due to invalid IL or missing references)
			//IL_1938: Unknown result type (might be due to invalid IL or missing references)
			//IL_196d: Unknown result type (might be due to invalid IL or missing references)
			//IL_1977: Expected O, but got Unknown
			//IL_0dbe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0dcd: Unknown result type (might be due to invalid IL or missing references)
			//IL_0ddc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0df2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0df8: 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_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_02f7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0306: Unknown result type (might be due to invalid IL or missing references)
			//IL_0315: Unknown result type (might be due to invalid IL or missing references)
			//IL_031f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0324: 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_032b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0339: Unknown result type (might be due to invalid IL or missing references)
			//IL_033c: Unknown result type (might be due to invalid IL or missing references)
			//IL_043b: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0459: Unknown result type (might be due to invalid IL or missing references)
			//IL_045e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0463: Unknown result type (might be due to invalid IL or missing references)
			//IL_0465: Unknown result type (might be due to invalid IL or missing references)
			//IL_046a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0478: Unknown result type (might be due to invalid IL or missing references)
			//IL_047b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				MerchantNPCsPlugin.Logger.LogInfo((object)"CreateUI method called");
				int num = 0;
				while (GUIManager.Instance == null && num < 5)
				{
					MerchantNPCsPlugin.Logger.LogWarning((object)$"GUIManager.Instance is null. Waiting for it to be available (attempt {num + 1}/5)...");
					Thread.Sleep(500);
					num++;
				}
				if (GUIManager.Instance == null)
				{
					MerchantNPCsPlugin.Logger.LogError((object)"GUIManager.Instance is still null after waiting. UI creation failed.");
					return;
				}
				MerchantNPCsPlugin.Logger.LogInfo((object)"GUIManager.Instance is available");
				num = 0;
				while ((Object)(object)GUIManager.CustomGUIFront == (Object)null && num < 5)
				{
					MerchantNPCsPlugin.Logger.LogWarning((object)$"GUIManager.CustomGUIFront is null. Waiting for it to be available (attempt {num + 1}/5)...");
					Thread.Sleep(500);
					num++;
				}
				if ((Object)(object)GUIManager.CustomGUIFront == (Object)null)
				{
					MerchantNPCsPlugin.Logger.LogError((object)"GUIManager.CustomGUIFront is still null after waiting. UI creation failed.");
					return;
				}
				MerchantNPCsPlugin.Logger.LogInfo((object)"GUIManager.CustomGUIFront is available");
				MerchantNPCsPlugin.Logger.LogInfo((object)"Creating main UI panel...");
				MerchantNPCsPlugin.Logger.LogInfo((object)"Creating UI panel with GUIManager.Instance.CreateWoodpanel...");
				try
				{
					_uiPanel = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-400f, 0f), 800f, 600f, true);
					if ((Object)(object)_uiPanel == (Object)null)
					{
						MerchantNPCsPlugin.Logger.LogError((object)"CreateWoodpanel returned null");
						return;
					}
					MerchantNPCsPlugin.Logger.LogInfo((object)"UI panel created successfully");
					((Object)_uiPanel).name = "MerchantUI_Panel";
					if (string.IsNullOrEmpty(_merchantType))
					{
						ShowMerchantMessage("Welcome to my shop!");
					}
					else
					{
						ShowMerchantMessage("Welcome to " + _merchantType + "'s shop!");
					}
					Canvas component = _uiPanel.GetComponent<Canvas>();
					if ((Object)(object)component != (Object)null)
					{
						component.sortingOrder = 100;
						MerchantNPCsPlugin.Logger.LogInfo((object)$"Set UI panel canvas sorting order to {component.sortingOrder}");
					}
					else
					{
						MerchantNPCsPlugin.Logger.LogWarning((object)"Could not find Canvas component on UI panel");
					}
					MerchantNPCsPlugin.Logger.LogInfo((object)"UI panel named 'MerchantUI_Panel'");
				}
				catch (Exception ex)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("Error creating UI panel: " + ex.Message + "\n" + ex.StackTrace));
					return;
				}
				((Object)_uiPanel).name = "MerchantUIPanel";
				_uiPanel.SetActive(false);
				MerchantNPCsPlugin.Logger.LogInfo((object)"Creating merchant name text...");
				try
				{
					GUIManager instance = GUIManager.Instance;
					Transform transform = _uiPanel.transform;
					Vector2 val = new Vector2(0.5f, 1f);
					Vector2 val2 = new Vector2(0.5f, 1f);
					Vector2 val3 = new Vector2(0f, -40f);
					Color valheimOrange = GUIManager.Instance.ValheimOrange;
					Color black = Color.black;
					GameObject val4 = instance.CreateText("Merchant", transform, val, val2, val3, GUIManager.Instance.AveriaSerifBold, 25, valheimOrange, true, black, 300f, 40f, false);
					if ((Object)(object)val4 == (Object)null)
					{
						MerchantNPCsPlugin.Logger.LogError((object)"CreateText returned null for merchant name text");
						return;
					}
					_merchantNameText = val4.GetComponent<Text>();
					if ((Object)(object)_merchantNameText == (Object)null)
					{
						MerchantNPCsPlugin.Logger.LogError((object)"Failed to get Text component from merchant name object");
						return;
					}
					_merchantNameText.alignment = (TextAnchor)4;
					((Object)_merchantNameText).name = "MerchantUI_MerchantNameText";
					MerchantNPCsPlugin.Logger.LogInfo((object)"Merchant name text created successfully");
				}
				catch (Exception ex2)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("Error creating merchant name text: " + ex2.Message + "\n" + ex2.StackTrace));
					return;
				}
				try
				{
					MerchantNPCsPlugin.Logger.LogInfo((object)"Creating prices info text...");
					GUIManager instance2 = GUIManager.Instance;
					Transform transform2 = _uiPanel.transform;
					Vector2 val5 = new Vector2(0.5f, 1f);
					Vector2 val6 = new Vector2(0.5f, 1f);
					Vector2 val7 = new Vector2(0f, -70f);
					Color black = Color.yellow;
					Color valheimOrange = Color.black;
					GameObject val8 = instance2.CreateText("All prices in coins", transform2, val5, val6, val7, GUIManager.Instance.AveriaSerif, 16, black, true, valheimOrange, 300f, 30f, false);
					if ((Object)(object)val8 != (Object)null)
					{
						Text component2 = val8.GetComponent<Text>();
						if ((Object)(object)component2 != (Object)null)
						{
							component2.alignment = (TextAnchor)4;
							((Object)component2).name = "MerchantUI_PricesInfoText";
							MerchantNPCsPlugin.Logger.LogInfo((object)"Prices info text created successfully");
						}
					}
				}
				catch (Exception ex3)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("Error creating prices info text: " + ex3.Message + "\n" + ex3.StackTrace));
				}
				try
				{
					MerchantNPCsPlugin.Logger.LogInfo((object)"Creating buy section title...");
					GameObject val9 = GUIManager.Instance.CreateText("Buy", _uiPanel.transform, new Vector2(0f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -90f), GUIManager.Instance.AveriaSerif, 20, GUIManager.Instance.ValheimYellow, true, Color.black, 380f, 30f, false);
					if ((Object)(object)val9 == (Object)null)
					{
						MerchantNPCsPlugin.Logger.LogError((object)"Failed to create buy title object");
					}
					else
					{
						Text component3 = val9.GetComponent<Text>();
						if ((Object)(object)component3 == (Object)null)
						{
							MerchantNPCsPlugin.Logger.LogError((object)"Failed to get Text component from buy title object");
						}
						else
						{
							component3.alignment = (TextAnchor)4;
							MerchantNPCsPlugin.Logger.LogInfo((object)"Buy section title created successfully");
						}
					}
				}
				catch (Exception ex4)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("Error creating buy section title: " + ex4.Message + "\n" + ex4.StackTrace));
				}
				try
				{
					MerchantNPCsPlugin.Logger.LogInfo((object)"Creating buy search input...");
					GameObject val10 = GUIManager.Instance.CreateInputField(_uiPanel.transform, new Vector2(0f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -120f), (ContentType)0, (string)null, 16, 380f, 30f);
					if ((Object)(object)val10 == (Object)null)
					{
						MerchantNPCsPlugin.Logger.LogError((object)"Failed to create buy search input object");
					}
					else
					{
						_buySearchInput = val10.GetComponent<InputField>();
						if ((Object)(object)_buySearchInput == (Object)null)
						{
							MerchantNPCsPlugin.Logger.LogError((object)"Failed to get InputField component from buy search object");
						}
						else
						{
							if ((Object)(object)_buySearchInput.placeholder == (Object)null)
							{
								MerchantNPCsPlugin.Logger.LogError((object)"Buy search input placeholder is null");
							}
							else
							{
								Text component4 = ((Component)_buySearchInput.placeholder).GetComponent<Text>();
								if ((Object)(object)component4 == (Object)null)
								{
									MerchantNPCsPlugin.Logger.LogError((object)"Failed to get Text component from buy search placeholder");
								}
								else
								{
									component4.text = "Search...";
								}
							}
							((UnityEvent<string>)(object)_buySearchInput.onValueChanged).AddListener((UnityAction<string>)OnBuySearchChanged);
							MerchantNPCsPlugin.Logger.LogInfo((object)"Buy search input created successfully");
						}
					}
				}
				catch (Exception ex5)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("Error creating buy search input: " + ex5.Message + "\n" + ex5.StackTrace));
				}
				try
				{
					MerchantNPCsPlugin.Logger.LogInfo((object)"Creating buy items container with scroll view...");
					GameObject val11 = new GameObject("BuyContainer", new Type[1] { typeof(RectTransform) });
					val11.transform.SetParent(_uiPanel.transform, false);
					RectTransform component5 = val11.GetComponent<RectTransform>();
					component5.anchorMin = new Vector2(0f, 0.25f);
					component5.anchorMax = new Vector2(0.5f, 0.75f);
					component5.anchoredPosition = Vector2.zero;
					component5.sizeDelta = Vector2.zero;
					MerchantNPCsPlugin.Logger.LogInfo((object)$"Buy container rect: anchorMin={component5.anchorMin}, anchorMax={component5.anchorMax}");
					GameObject val12 = new GameObject("BuyItemsPanel", new Type[3]
					{
						typeof(RectTransform),
						typeof(CanvasRenderer),
						typeof(Image)
					});
					val12.transform.SetParent(val11.transform, false);
					RectTransform component6 = val12.GetComponent<RectTransform>();
					component6.anchorMin = new Vector2(0f, 0f);
					component6.anchorMax = new Vector2(1f, 1f);
					component6.offsetMin = new Vector2(10f, 10f);
					component6.offsetMax = new Vector2(-10f, -10f);
					Image component7 = val12.GetComponent<Image>();
					((Graphic)component7).color = new Color(0.1f, 0.1f, 0.1f, 0.3f);
					GameObject val13 = new GameObject("BuyScroll", new Type[2]
					{
						typeof(RectTransform),
						typeof(ScrollRect)
					});
					val13.transform.SetParent(val12.transform, false);
					RectTransform component8 = val13.GetComponent<RectTransform>();
					component8.anchorMin = new Vector2(0f, 0f);
					component8.anchorMax = new Vector2(1f, 1f);
					component8.offsetMin = Vector2.zero;
					component8.offsetMax = Vector2.zero;
					ScrollRect component9 = val13.GetComponent<ScrollRect>();
					component9.horizontal = false;
					component9.vertical = true;
					GameObject val14 = new GameObject("Viewport", new Type[3]
					{
						typeof(RectTransform),
						typeof(Mask),
						typeof(Image)
					});
					val14.transform.SetParent(val13.transform, false);
					RectTransform component10 = val14.GetComponent<RectTransform>();
					component10.anchorMin = new Vector2(0f, 0f);
					component10.anchorMax = new Vector2(1f, 1f);
					component10.offsetMin = Vector2.zero;
					component10.offsetMax = Vector2.zero;
					Mask component11 = val14.GetComponent<Mask>();
					component11.showMaskGraphic = false;
					Image component12 = val14.GetComponent<Image>();
					((Graphic)component12).color = Color.white;
					GameObject val15 = new GameObject("Content", new Type[3]
					{
						typeof(RectTransform),
						typeof(VerticalLayoutGroup),
						typeof(ContentSizeFitter)
					});
					val15.transform.SetParent(val14.transform, false);
					_buyItemsContainer = val15.GetComponent<RectTransform>();
					_buyItemsContainer.anchorMin = new Vector2(0f, 1f);
					_buyItemsContainer.anchorMax = new Vector2(1f, 1f);
					_buyItemsContainer.pivot = new Vector2(0.5f, 1f);
					_buyItemsContainer.anchoredPosition = new Vector2(0f, -50f);
					_buyItemsContainer.sizeDelta = new Vector2(0f, 0f);
					VerticalLayoutGroup component13 = val15.GetComponent<VerticalLayoutGroup>();
					((HorizontalOrVerticalLayoutGroup)component13).spacing = 10f;
					((LayoutGroup)component13).padding = new RectOffset(10, 10, 10, 10);
					((LayoutGroup)component13).childAlignment = (TextAnchor)1;
					((HorizontalOrVerticalLayoutGroup)component13).childControlWidth = true;
					((HorizontalOrVerticalLayoutGroup)component13).childControlHeight = false;
					((HorizontalOrVerticalLayoutGroup)component13).childForceExpandWidth = true;
					((HorizontalOrVerticalLayoutGroup)component13).childForceExpandHeight = false;
					((HorizontalOrVerticalLayoutGroup)component13).reverseArrangement = false;
					ContentSizeFitter component14 = val15.GetComponent<ContentSizeFitter>();
					component14.horizontalFit = (FitMode)0;
					component14.verticalFit = (FitMode)2;
					component9.viewport = component10;
					component9.content = _buyItemsContainer;
					MerchantNPCsPlugin.Logger.LogInfo((object)$"Buy container position: anchorMin={_buyItemsContainer.anchorMin}, anchorMax={_buyItemsContainer.anchorMax}, pivot={_buyItemsContainer.pivot}, position={_buyItemsContainer.anchoredPosition}");
					MerchantNPCsPlugin.Logger.LogInfo((object)$"Buy viewport position: anchorMin={component10.anchorMin}, anchorMax={component10.anchorMax}");
					MerchantNPCsPlugin.Logger.LogInfo((object)"Buy items container created successfully");
				}
				catch (Exception ex6)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("Error creating buy items container: " + ex6.Message + "\n" + ex6.StackTrace));
					if ((Object)(object)_buyItemsContainer == (Object)null)
					{
						MerchantNPCsPlugin.Logger.LogInfo((object)"Creating fallback buy items container");
						GameObject val16 = new GameObject("BuyItemsContainer", new Type[1] { typeof(RectTransform) });
						val16.transform.SetParent(_uiPanel.transform, false);
						_buyItemsContainer = val16.GetComponent<RectTransform>();
					}
				}
				try
				{
					MerchantNPCsPlugin.Logger.LogInfo((object)"Creating sell section title...");
					GameObject val17 = GUIManager.Instance.CreateText("Sell", _uiPanel.transform, new Vector2(0.5f, 1f), new Vector2(1f, 1f), new Vector2(0f, -90f), GUIManager.Instance.AveriaSerif, 20, GUIManager.Instance.ValheimYellow, true, Color.black, 380f, 30f, false);
					if ((Object)(object)val17 == (Object)null)
					{
						MerchantNPCsPlugin.Logger.LogError((object)"Failed to create sell title object");
					}
					else
					{
						Text component15 = val17.GetComponent<Text>();
						if ((Object)(object)component15 == (Object)null)
						{
							MerchantNPCsPlugin.Logger.LogError((object)"Failed to get Text component from sell title object");
						}
						else
						{
							component15.alignment = (TextAnchor)4;
							MerchantNPCsPlugin.Logger.LogInfo((object)"Sell section title created successfully");
						}
					}
				}
				catch (Exception ex7)
				{
					MerchantNPCsPlugin.Logger.LogError((object)("Error creating sell section title: " + ex7.Message + "\n" + ex7.StackTrace));
				}
				try
				{
					MerchantNPCsPlugin.Logger.LogInfo((object)"Creating sell search input...");
					GameObject val18 = GUIManager.Instance.CreateInputField(_uiPanel.transform, new Vector2(0.5f, 1f), new Vector2(1f, 1f), new Vector2(0f, -120f), (ContentType)0, (string)null, 16, 380f, 30f);
					if ((Object)(object)val18 == (Object)null)
					{
						MerchantNPCsPlugin.Logger.LogError((object)"Failed to create sell search input object");
					}
					else
					{