Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of MerchantNPCs v1.0.2
MerchantNPCs.dll
Decompiled 11 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.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", "1.0.2")] [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 = "1.0.2"; internal static ManualLogSource Logger; private const string AssetBundleName = "merchant1_ru"; private AssetBundle _merchantAssetBundle; private MerchantPieces _merchantPieces; private ConfigEntry<bool> _isModEnabled; public static ConfigEntry<int> SellPercentage; 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)) { continue; } 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)); } } } } catch (Exception ex) { Logger.LogError((object)("Error extracting config files: " + ex.Message)); } } private void Awake() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: 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"); SellPercentage = ((BaseUnityPlugin)this).Config.Bind<int>("Trading", "SellPercentage", 50, new ConfigDescription("Percentage of buy price received when selling items (1-100)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>())); if (_isModEnabled.Value) { InitializeMerchantCostConfigs(); ExtractEmbeddedConfigs(); PrefabManager.OnVanillaPrefabsAvailable += AddMerchantPieces; ZoneManager.OnVanillaLocationsAvailable += InitializeMerchantTrading; Harmony val = new Harmony("ruijven.merchantnpcs"); val.PatchAll(Assembly.GetExecutingAssembly()); } } private void InitializeMerchantCostConfigs() { 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; } 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(); } 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(); string[] array = allAssetNames; foreach (string text in array) { } string[] array2 = (from name in _merchantAssetBundle.GetAllAssetNames() where (Object)(object)_merchantAssetBundle.LoadAsset<GameObject>(name) != (Object)null select name).ToArray(); string[] array3 = (from name in _merchantAssetBundle.GetAllAssetNames() where (Object)(object)_merchantAssetBundle.LoadAsset<Sprite>(name) != (Object)null select name).ToArray(); string[] array4 = (from name in _merchantAssetBundle.GetAllAssetNames() where (Object)(object)_merchantAssetBundle.LoadAsset<Material>(name) != (Object)null select name).ToArray(); string[] array5 = (from name in _merchantAssetBundle.GetAllAssetNames() where (Object)(object)_merchantAssetBundle.LoadAsset<Texture>(name) != (Object)null select name).ToArray(); string[] array6 = (from name in _merchantAssetBundle.GetAllAssetNames() where (Object)(object)_merchantAssetBundle.LoadAsset<AnimationClip>(name) != (Object)null select name).ToArray(); } 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"); } 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(); 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); num++; } catch (Exception ex) { Logger.LogWarning((object)("Failed to register prefab " + fileNameWithoutExtension + ": " + ex.Message)); } } } 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) { num2++; } } 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) { num3++; } } 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) { num4++; } } 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) { num5++; } } } 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(); } else { Logger.LogError((object)"MerchantManager instance is null"); } try { MerchantUI.Initialize(); } catch (Exception ex) { Logger.LogError((object)("Error initializing merchant UI instance: " + ex.Message + "\n" + ex.StackTrace)); } } 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 => (int)((float)BuyPrice * ((float)MerchantNPCsPlugin.SellPercentage.Value / 100f)); public int Cost => BuyPrice; 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(); } } 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; } 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; } } 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; } } 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; } } 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; } } } 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; } } 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; if (!(component.m_itemData.m_shared.m_name != item.ItemName)) { } } 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")) { return _merchantInventories["Mountains"]; } if (merchantType == "Mountains" && !_merchantInventories.ContainsKey("Mountains") && _merchantInventories.ContainsKey("Mountain")) { return _merchantInventories["Mountain"]; } return null; } public bool BuyItem(Player player, MerchantItem item, int quantity = 1) { //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03b1: 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; } if (!item.IsAvailable) { ((Character)player).Message((MessageType)2, "This item is not available for purchase", 0, (Sprite)null); return false; } int amount = item.BuyPrice * quantity; if (!HasEnoughCoins(player, amount)) { ((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)) { ((Character)player).Message((MessageType)2, "You don't have enough space for that", 0, (Sprite)null); return false; } RemoveCoins(player, amount); 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); } 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; 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); } 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; 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; break; } } } } catch (Exception ex4) { MerchantNPCsPlugin.Logger.LogError((object)("Exception when searching ObjectDB items: " + ex4.Message)); } } } if ((Object)(object)val == (Object)null) { try { 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; ((Character)player).Message((MessageType)2, $"You purchased {quantity}x {name3}", 0, (Sprite)null); ((Humanoid)player).GetInventory().Changed(); if (val3.IsEquipable()) { try { 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)); } 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; } } 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; } } 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; } 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 { return ((Humanoid)player).GetInventory().CanAddItem(val, quantity); } catch (Exception ex5) { MerchantNPCsPlugin.Logger.LogError((object)("Exception when checking CanAddItem: " + ex5.Message)); return true; } } } public class MerchantUI : MonoBehaviour { private static readonly Color MerchantBlue = new Color(0.1f, 0.2f, 0.4f, 1f); private static readonly Color MerchantDarkBlue = new Color(0.05f, 0.1f, 0.2f, 1f); private static readonly Color MerchantGold = new Color(0.9f, 0.7f, 0.2f, 1f); private static readonly Color PanelTint = new Color(0.05f, 0.1f, 0.2f, 0.95f); private static readonly Color MerchantButtonNormal = new Color(0.25f, 0.35f, 0.55f, 1f); private static readonly Color MerchantButtonHighlighted = new Color(0.35f, 0.45f, 0.65f, 1f); private static readonly Color MerchantButtonPressed = new Color(0.2f, 0.3f, 0.5f, 1f); private static readonly Color MerchantTextColor = new Color(0.9f, 0.8f, 0.5f, 1f); private static readonly string ConfigFolderPath = Path.Combine(Paths.ConfigPath, "MerchantNPCs"); private static readonly string BackgroundImagePath = Path.Combine(ConfigFolderPath, "merchantnpcscanvas.png"); private static readonly Color MerchantTitleColor = new Color(1f, 0.8f, 0.4f, 1f); 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_0fe6: Unknown result type (might be due to invalid IL or missing references) //IL_0fed: Expected O, but got Unknown //IL_1a5a: Unknown result type (might be due to invalid IL or missing references) //IL_1a61: Expected O, but got Unknown //IL_05d4: Unknown result type (might be due to invalid IL or missing references) //IL_05e3: Unknown result type (might be due to invalid IL or missing references) //IL_05f2: Unknown result type (might be due to invalid IL or missing references) //IL_0608: Unknown result type (might be due to invalid IL or missing references) //IL_060e: Unknown result type (might be due to invalid IL or missing references) //IL_06ec: Unknown result type (might be due to invalid IL or missing references) //IL_06fb: Unknown result type (might be due to invalid IL or missing references) //IL_070a: Unknown result type (might be due to invalid IL or missing references) //IL_087b: Unknown result type (might be due to invalid IL or missing references) //IL_0882: Expected O, but got Unknown //IL_08b0: Unknown result type (might be due to invalid IL or missing references) //IL_08c7: Unknown result type (might be due to invalid IL or missing references) //IL_08d4: Unknown result type (might be due to invalid IL or missing references) //IL_08e1: Unknown result type (might be due to invalid IL or missing references) //IL_08f8: Unknown result type (might be due to invalid IL or missing references) //IL_0904: Unknown result type (might be due to invalid IL or missing references) //IL_094b: Unknown result type (might be due to invalid IL or missing references) //IL_0952: Expected O, but got Unknown //IL_097c: Unknown result type (might be due to invalid IL or missing references) //IL_0993: Unknown result type (might be due to invalid IL or missing references) //IL_09aa: Unknown result type (might be due to invalid IL or missing references) //IL_09c1: Unknown result type (might be due to invalid IL or missing references) //IL_09eb: Unknown result type (might be due to invalid IL or missing references) //IL_0a1b: Unknown result type (might be due to invalid IL or missing references) //IL_0a22: Expected O, but got Unknown //IL_0a4c: Unknown result type (might be due to invalid IL or missing references) //IL_0a63: Unknown result type (might be due to invalid IL or missing references) //IL_0a70: Unknown result type (might be due to invalid IL or missing references) //IL_0a7d: Unknown result type (might be due to invalid IL or missing references) //IL_0ad5: Unknown result type (might be due to invalid IL or missing references) //IL_0adc: Expected O, but got Unknown //IL_0b06: Unknown result type (might be due to invalid IL or missing references) //IL_0b1d: Unknown result type (might be due to invalid IL or missing references) //IL_0b34: Unknown result type (might be due to invalid IL or missing references) //IL_0b4b: Unknown result type (might be due to invalid IL or missing references) //IL_0b62: Unknown result type (might be due to invalid IL or missing references) //IL_0b9e: Unknown result type (might be due to invalid IL or missing references) //IL_0bce: Unknown result type (might be due to invalid IL or missing references) //IL_0bd5: Expected O, but got Unknown //IL_0bff: Unknown result type (might be due to invalid IL or missing references) //IL_0c16: Unknown result type (might be due to invalid IL or missing references) //IL_0c23: Unknown result type (might be due to invalid IL or missing references) //IL_0c3a: Unknown result type (might be due to invalid IL or missing references) //IL_0c64: 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_0cd2: Expected O, but got Unknown //IL_0cfc: Unknown result type (might be due to invalid IL or missing references) //IL_0d13: Unknown result type (might be due to invalid IL or missing references) //IL_0d20: Unknown result type (might be due to invalid IL or missing references) //IL_0d2d: Unknown result type (might be due to invalid IL or missing references) //IL_0d55: Unknown result type (might be due to invalid IL or missing references) //IL_0d92: Unknown result type (might be due to invalid IL or missing references) //IL_0d99: Expected O, but got Unknown //IL_0dcb: Unknown result type (might be due to invalid IL or missing references) //IL_0de6: Unknown result type (might be due to invalid IL or missing references) //IL_0e01: Unknown result type (might be due to invalid IL or missing references) //IL_0e1c: Unknown result type (might be due to invalid IL or missing references) //IL_0e37: Unknown result type (might be due to invalid IL or missing references) //IL_0e62: Unknown result type (might be due to invalid IL or missing references) //IL_0e6c: Expected O, but got Unknown //IL_0eee: Unknown result type (might be due to invalid IL or missing references) //IL_0f01: Unknown result type (might be due to invalid IL or missing references) //IL_0f14: Unknown result type (might be due to invalid IL or missing references) //IL_0f27: Unknown result type (might be due to invalid IL or missing references) //IL_0f49: Unknown result type (might be due to invalid IL or missing references) //IL_0f55: Unknown result type (might be due to invalid IL or missing references) //IL_1160: Unknown result type (might be due to invalid IL or missing references) //IL_116f: Unknown result type (might be due to invalid IL or missing references) //IL_117e: Unknown result type (might be due to invalid IL or missing references) //IL_12ef: Unknown result type (might be due to invalid IL or missing references) //IL_12f6: Expected O, but got Unknown //IL_1324: Unknown result type (might be due to invalid IL or missing references) //IL_133b: Unknown result type (might be due to invalid IL or missing references) //IL_1348: Unknown result type (might be due to invalid IL or missing references) //IL_1355: Unknown result type (might be due to invalid IL or missing references) //IL_136c: Unknown result type (might be due to invalid IL or missing references) //IL_1378: Unknown result type (might be due to invalid IL or missing references) //IL_13bf: Unknown result type (might be due to invalid IL or missing references) //IL_13c6: Expected O, but got Unknown //IL_13f0: Unknown result type (might be due to invalid IL or missing references) //IL_1407: Unknown result type (might be due to invalid IL or missing references) //IL_141e: Unknown result type (might be due to invalid IL or missing references) //IL_1435: Unknown result type (might be due to invalid IL or missing references) //IL_145f: Unknown result type (might be due to invalid IL or missing references) //IL_148f: Unknown result type (might be due to invalid IL or missing references) //IL_1496: Expected O, but got Unknown //IL_14c0: Unknown result type (might be due to invalid IL or missing references) //IL_14d7: Unknown result type (might be due to invalid IL or missing references) //IL_14e4: Unknown result type (might be due to invalid IL or missing references) //IL_14f1: 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_1550: Expected O, but got Unknown //IL_157a: Unknown result type (might be due to invalid IL or missing references) //IL_1591: Unknown result type (might be due to invalid IL or missing references) //IL_15a8: Unknown result type (might be due to invalid IL or missing references) //IL_15bf: Unknown result type (might be due to invalid IL or missing references) //IL_15d6: Unknown result type (might be due to invalid IL or missing references) //IL_1612: Unknown result type (might be due to invalid IL or missing references) //IL_1642: Unknown result type (might be due to invalid IL or missing references) //IL_1649: Expected O, but got Unknown //IL_1673: Unknown result type (might be due to invalid IL or missing references) //IL_168a: Unknown result type (might be due to invalid IL or missing references) //IL_1697: Unknown result type (might be due to invalid IL or missing references) //IL_16ae: Unknown result type (might be due to invalid IL or missing references) //IL_16d8: Unknown result type (might be due to invalid IL or missing references) //IL_173f: Unknown result type (might be due to invalid IL or missing references) //IL_1746: Expected O, but got Unknown //IL_1770: Unknown result type (might be due to invalid IL or missing references) //IL_1787: Unknown result type (might be due to invalid IL or missing references) //IL_1794: Unknown result type (might be due to invalid IL or missing references) //IL_17a1: Unknown result type (might be due to invalid IL or missing references) //IL_17c9: Unknown result type (might be due to invalid IL or missing references) //IL_1806: Unknown result type (might be due to invalid IL or missing references) //IL_180d: Expected O, but got Unknown //IL_183f: Unknown result type (might be due to invalid IL or missing references) //IL_185a: Unknown result type (might be due to invalid IL or missing references) //IL_1875: Unknown result type (might be due to invalid IL or missing references) //IL_1890: Unknown result type (might be due to invalid IL or missing references) //IL_18ab: Unknown result type (might be due to invalid IL or missing references) //IL_18d6: Unknown result type (might be due to invalid IL or missing references) //IL_18e0: Expected O, but got Unknown //IL_1962: Unknown result type (might be due to invalid IL or missing references) //IL_1975: Unknown result type (might be due to invalid IL or missing references) //IL_1988: Unknown result type (might be due to invalid IL or missing references) //IL_199b: Unknown result type (might be due to invalid IL or missing references) //IL_19bd: Unknown result type (might be due to invalid IL or missing references) //IL_19c9: Unknown result type (might be due to invalid IL or missing references) //IL_1aaa: Unknown result type (might be due to invalid IL or missing references) //IL_1ab9: Unknown result type (might be due to invalid IL or missing references) //IL_1ac8: Unknown result type (might be due to invalid IL or missing references) //IL_1ad9: Unknown result type (might be due to invalid IL or missing references) //IL_1adf: Unknown result type (might be due to invalid IL or missing references) //IL_1b79: Unknown result type (might be due to invalid IL or missing references) //IL_1b88: Unknown result type (might be due to invalid IL or missing references) //IL_1b97: Unknown result type (might be due to invalid IL or missing references) //IL_1bc6: Unknown result type (might be due to invalid IL or missing references) //IL_1bd0: Expected O, but got Unknown //IL_1bfd: Unknown result type (might be due to invalid IL or missing references) //IL_1c0c: Unknown result type (might be due to invalid IL or missing references) //IL_1c1b: Unknown result type (might be due to invalid IL or missing references) //IL_1c4a: Unknown result type (might be due to invalid IL or missing references) //IL_1c54: Expected O, but got Unknown //IL_1c81: Unknown result type (might be due to invalid IL or missing references) //IL_1c90: Unknown result type (might be due to invalid IL or missing references) //IL_1c9c: Unknown result type (might be due to invalid IL or missing references) //IL_1cc9: Unknown result type (might be due to invalid IL or missing references) //IL_1cd3: Expected O, but got Unknown //IL_1d00: Unknown result type (might be due to invalid IL or missing references) //IL_1d0f: Unknown result type (might be due to invalid IL or missing references) //IL_1d1b: Unknown result type (might be due to invalid IL or missing references) //IL_1d48: Unknown result type (might be due to invalid IL or missing references) //IL_1d52: Expected O, but got Unknown //IL_1d7f: Unknown result type (might be due to invalid IL or missing references) //IL_1d8e: Unknown result type (might be due to invalid IL or missing references) //IL_1d9a: Unknown result type (might be due to invalid IL or missing references) //IL_1dc7: Unknown result type (might be due to invalid IL or missing references) //IL_1dd1: Expected O, but got Unknown //IL_1dfe: Unknown result type (might be due to invalid IL or missing references) //IL_1e0d: Unknown result type (might be due to invalid IL or missing references) //IL_1e19: Unknown result type (might be due to invalid IL or missing references) //IL_1e3e: Unknown result type (might be due to invalid IL or missing references) //IL_1e48: Expected O, but got Unknown //IL_1e71: Unknown result type (might be due to invalid IL or missing references) //IL_1e80: Unknown result type (might be due to invalid IL or missing references) //IL_1e8c: Unknown result type (might be due to invalid IL or missing references) //IL_1eb1: Unknown result type (might be due to invalid IL or missing references) //IL_1ebb: Expected O, but got Unknown //IL_1ee4: Unknown result type (might be due to invalid IL or missing references) //IL_1ef3: Unknown result type (might be due to invalid IL or missing references) //IL_1f02: Unknown result type (might be due to invalid IL or missing references) //IL_1f37: Unknown result type (might be due to invalid IL or missing references) //IL_1f41: Expected O, but got Unknown //IL_1048: Unknown result type (might be due to invalid IL or missing references) //IL_1057: Unknown result type (might be due to invalid IL or missing references) //IL_1066: Unknown result type (might be due to invalid IL or missing references) //IL_107c: Unknown result type (might be due to invalid IL or missing references) //IL_1082: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_039a: Unknown result type (might be due to invalid IL or missing references) //IL_03a9: Unknown result type (might be due to invalid IL or missing references) //IL_03b3: Unknown result type (might be due to invalid IL or missing references) //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_03ba: Unknown result type (might be due to invalid IL or missing references) //IL_03bf: Unknown result type (might be due to invalid IL or missing references) //IL_03cd: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: 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_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_04de: Unknown result type (might be due to invalid IL or missing references) //IL_04ed: Unknown result type (might be due to invalid IL or missing references) //IL_04f2: Unknown result type (might be due to invalid IL or missing references) //IL_04f7: Unknown result type (might be due to invalid IL or missing references) //IL_04f9: Unknown result type (might be due to invalid IL or missing references) //IL_04fe: Unknown result type (might be due to invalid IL or missing references) //IL_050c: Unknown result type (might be due to invalid IL or missing references) //IL_050f: Unknown result type (might be due to invalid IL or missing references) //IL_01b5: 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); try { Image component = _uiPanel.GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).color = new Color(0.15f, 0.25f, 0.4f, 1f); MerchantNPCsPlugin.Logger.LogInfo((object)"Using blue tint background (custom background disabled)"); } else { MerchantNPCsPlugin.Logger.LogError((object)"Could not find Image component on UI panel"); } } catch (Exception ex) { MerchantNPCsPlugin.Logger.LogError((object)("Error applying custom background: " + ex.Message + "\n" + ex.StackTrace)); } 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 component2 = _uiPanel.GetComponent<Canvas>(); if ((Object)(object)component2 != (Object)null) { component2.sortingOrder = 100; MerchantNPCsPlugin.Logger.LogInfo((object)$"Set UI panel canvas sorting order to {component2.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 ex2) { MerchantNPCsPlugin.Logger.LogError((object)("Error creating UI panel: " + ex2.Message + "\n" + ex2.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 ex3) { MerchantNPCsPlugin.Logger.LogError((object)("Error creating merchant name text: " + ex3.Message + "\n" + ex3.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 component3 = val8.GetComponent<Text>(); if ((Object)(object)component3 != (Object)null) { component3.alignment = (TextAnchor)4; ((Object)component3).name = "MerchantUI_PricesInfoText"; MerchantNPCsPlugin.Logger.LogInfo((object)"Prices info text created successfully"); } } } catch (Exception ex4) { MerchantNPCsPlugin.Logger.LogError((object)("Error creating prices info text: " + ex4.Message + "\n" + ex4.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 component4 = val9.GetComponent<Text>(); if ((Object)(object)component4 == (Object)null) { MerchantNPCsPlugin.Logger.LogError((object)"Failed to get Text component from buy title object"); } else { component4.alignment = (TextAnchor)4; MerchantNPCsPlugin.Logger.LogInfo((object)"Buy section title created successfully"); } } } catch (Exception ex5) { MerchantNPCsPlugin.Logger.LogError((object)("Error creating buy section title: " + ex5.Message + "\n" + ex5.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 component5 = ((Component)_buySearchInput.placeholder).GetComponent<Text>(); if ((Object)(object)component5 == (Object)null) { MerchantNPCsPlugin.Logger.LogError((object)"Failed to get Text component from buy search placeholder"); } else { component5.text = "Search..."; } } ((UnityEvent<string>)(object)_buySearchInput.onValueChanged).AddListener((UnityAction<string>)OnBuySearchChanged); MerchantNPCsPlugin.Logger.LogInfo((object)"Buy search input created successfully"); } } } catch (Exception ex6) { MerchantNPCsPlugin.Logger.LogError((object)("Error creating buy search input: " + ex6.Message + "\n" + ex6.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 component6 = val11.GetComponent<RectTransform>(); component6.anchorMin = new Vector2(0f, 0.25f); component6.anchorMax = new Vector2(0.5f, 0.75f); component6.anchoredPosition = Vector2.zero; component6.sizeDelta = Vector2.zero; MerchantNPCsPlugin.Logger.LogInfo((object)$"Buy container rect: anchorMin={component6.anchorMin}, anchorMax={component6.anchorMax}"); GameObject val12 = new GameObject("BuyItemsPanel", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val12.transform.SetParent(val11.transform, false); RectTransform component7 = val12.GetComponent<RectTransform>(); component7.anchorMin = new Vector2(0f, 0f); component7.anchorMax = new Vector2(1f, 1f); component7.offsetMin = new Vector2(10f, 10f); component7.offsetMax = new Vector2(-10f, -10f); Image component8 = val12.GetComponent<Image>(); ((Graphic)component8).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 component9 = val13.GetComponent<RectTransform>(); component9.anchorMin = new Vector2(0f, 0f); component9.anchorMax = new Vector2(1f, 1f); component9.offsetMin = Vector2.zero; component9.offsetMax = Vector2.zero; ScrollRect component10 = val13.GetComponent<ScrollRect>(); component10.horizontal = false; component10.vertical = true; GameObject val14 = new GameObject("BuyScrollbar", new Type[3] { typeof(RectTransform), typeof(Scrollbar), typeof(Image) }); val14.transform.SetParent(val13.transform, false); RectTransform component11 = val14.GetComponent<RectTransform>(); component11.anchorMin = new Vector2(1f, 0f); component11.anchorMax = new Vector2(1f, 1f); component11.pivot = new Vector2(1f, 0.5f); component11.anchoredPosition = new Vector2(0f, 0f); component11.sizeDelta = new Vector2(20f, 0f); Scrollbar component12 = val14.GetComponent<Scrollbar>(); component12.direction = (Direction)2; Image component13 = val14.GetComponent<Image>(); ((Graphic)component13).color = new Color(0.3f, 0.3f, 0.3f, 0.8f); GameObject val15 = new GameObject("Handle", new Type[2] { typeof(RectTransform), typeof(Image) }); val15.transform.SetParent(val14.transform, false); RectTransform component14 = val15.GetComponent<RectTransform>(); component14.anchorMin = new Vector2(0f, 0f); component14.anchorMax = new Vector2(1f, 0.2f); component14.sizeDelta = Vector2.zero; component14.pivot = new Vector2(0.5f, 0.5f); Image component15 = val15.GetComponent<Image>(); ((Graphic)component15).color = new Color(0.7f, 0.7f, 0.7f, 0.8f); component12.handleRect = component14; component10.verticalScrollbar = component12; component10.verticalScrollbarVisibility = (ScrollbarVisibility)0; component10.verticalScrollbarSpacing = 5f; GameObject val16 = new GameObject("Viewport", new Type[3] { typeof(RectTransform), typeof(Mask), typeof(Image) }); val16.transform.SetParent(val13.transform, false); RectTransform component16 = val16.GetComponent<RectTransform>(); component16.anchorMin = new Vector2(0f, 0f); component16.anchorMax = new Vector2(1f, 1f); component16.offsetMin = Vector2.zero; component16.offsetMax = Vector2.zero; Mask component17 = val16.GetComponent<Mask>(); component17.showMaskGraphic = false; Image component18 = val16.GetComponent<Image>(); ((Graphic)component18).color = Color.white; GameObject val17 = new GameObject("Content", new Type[3] { typeof(RectTransform), typeof(VerticalLayoutGroup), typeof(ContentSizeFitter) }); val17.transform.SetParent(val16.transform, false); _buyItemsContainer = val17.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 component19 = val17.GetComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)component19).spacing = 10f; ((LayoutGroup)component19).padding = new RectOffset(10, 10, 10, 10); ((LayoutGroup)component19).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)component19).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)component19).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)component19).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)component19).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)component19).reverseArrangement = false; ContentSizeFitter component20 = val17.GetComponent<ContentSizeFitter>(); component20.horizontalFit = (FitMode)0; component20.verticalFit = (FitMode)2; component10.viewport = component16; component10.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={component16.anchorMin}, anchorMax={component16.anchorMax}"); MerchantNPCsPlugin.Logger.LogInfo((object)"Buy items container created successfully"); } catch (Exception ex7) { MerchantNPCsPlugin.Logger.LogError((object)("Error creating buy items container: " + ex7.Message + "\n" + ex7.StackTrace)); if ((Object)(object)_buyItemsContainer == (Object)null) { MerchantNPCsPlugin.Logger.LogInfo((object)"Creating fallback buy items container"); GameObject val18 = new GameObject("BuyItemsContainer", new Type[1] { typeof(RectTransform) }); val18.transform.SetParent(_uiPanel.transform, false); _buyItemsContainer = val18.GetComponent<RectTransform>(); } } try { MerchantNPCsPlugin.Logger.LogInfo((object)"Creating sell section title..."); GameObject val19 = 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)val19 == (Object)null) { MerchantNPCsPlugin.Logger.LogError((object)"Failed to create sell title object"); } else { Text component21 = v