Decompiled source of CarlosMMOEconomy v1.0.2

plugins/CarlosMMOEconomy.dll

Decompiled an hour ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("CarlosMMOEconomy")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CarlosMMOEconomy")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("814da345-2fc5-4370-88f0-9437d2f498ba")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace CarlosMMO;

[BepInPlugin("carlosmmo.economy", "Carlos MMO Economy", "1.5.4")]
public class CarlosMMOEconomy : BaseUnityPlugin
{
	private class ShopOffer
	{
		public string PrefabName;

		public string DisplayName;

		public int Price;

		public int Amount;

		public ShopOffer(string prefabName, string displayName, int price, int amount)
		{
			PrefabName = prefabName;
			DisplayName = displayName;
			Price = price;
			Amount = amount;
		}
	}

	[HarmonyPatch(typeof(Character), "OnDeath")]
	private static class Character_OnDeath_Patch
	{
		private static void Postfix(Character __instance)
		{
			//IL_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if ((Object)(object)_instance == (Object)null || (Object)(object)__instance == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null || __instance.IsPlayer())
				{
					return;
				}
				string text = (((Object)(object)((Component)__instance).gameObject != (Object)null) ? ((Object)((Component)__instance).gameObject).name : string.Empty);
				if (string.IsNullOrEmpty(text))
				{
					return;
				}
				int bossReward = GetBossReward(text);
				if (bossReward > 0)
				{
					float num = Vector3.Distance(((Component)__instance).transform.position, ((Component)Player.m_localPlayer).transform.position);
					if (!(num > 120f))
					{
						_instance.AddCoins(bossReward, showMessage: true, "boss");
					}
				}
			}
			catch (Exception ex)
			{
				if ((Object)(object)_instance != (Object)null)
				{
					((BaseUnityPlugin)_instance).Logger.LogWarning((object)("Falha no reward de boss: " + ex.Message));
				}
			}
		}

		private static int GetBossReward(string prefabName)
		{
			string text = prefabName.ToLowerInvariant();
			if (text.Contains("eikthyr"))
			{
				return 100;
			}
			if (text.Contains("gdking") || text.Contains("elder"))
			{
				return 200;
			}
			if (text.Contains("bonemass"))
			{
				return 300;
			}
			if (text.Contains("dragon") || text.Contains("moder"))
			{
				return 400;
			}
			if (text.Contains("goblinking") || text.Contains("yagluth"))
			{
				return 500;
			}
			if (text.Contains("seekerqueen") || text.Contains("queen"))
			{
				return 700;
			}
			return 0;
		}
	}

	[HarmonyPatch(typeof(CraftingStation), "Interact")]
	private static class CraftingStation_Interact_Patch
	{
		private static bool Prefix(CraftingStation __instance, Humanoid user, bool repeat, bool alt)
		{
			try
			{
				if ((Object)(object)_instance == (Object)null || (Object)(object)__instance == (Object)null || (Object)(object)user == (Object)null)
				{
					return true;
				}
				if ((Object)(object)Player.m_localPlayer == (Object)null)
				{
					return true;
				}
				if ((Object)(object)user != (Object)(object)Player.m_localPlayer)
				{
					return true;
				}
				GameObject gameObject = ((Component)__instance).gameObject;
				if (!_instance.IsMarketBenchObject(gameObject))
				{
					return true;
				}
				if (repeat)
				{
					return false;
				}
				_instance.ToggleMarketMenu(gameObject);
				return false;
			}
			catch (Exception ex)
			{
				if ((Object)(object)_instance != (Object)null)
				{
					((BaseUnityPlugin)_instance).Logger.LogWarning((object)("Falha em CraftingStation.Interact patch: " + ex.Message));
				}
				return true;
			}
		}
	}

	[HarmonyPatch(typeof(CraftingStation), "GetHoverText")]
	private static class CraftingStation_GetHoverText_Patch
	{
		private static void Postfix(CraftingStation __instance, ref string __result)
		{
			try
			{
				if (!((Object)(object)_instance == (Object)null) && !((Object)(object)__instance == (Object)null))
				{
					GameObject gameObject = ((Component)__instance).gameObject;
					if (_instance.IsMarketBenchObject(gameObject))
					{
						__result = "Bancada Mercado\n[<color=yellow><b>$KEY_Use</b></color>] Abrir mercado\n[<color=yellow><b>Mouse Wheel</b></color>] Rolar ofertas\n[<color=yellow><b>Keypad 5</b></color>] Comprar oferta\n[<color=yellow><b>Keypad 7</b></color>] Ver saldo em CriptoVikings";
					}
				}
			}
			catch
			{
			}
		}
	}

	[HarmonyPatch(typeof(PlayerController), "TakeInput")]
	private static class PlayerController_TakeInput_Patch
	{
		private static bool Prefix(ref bool __result)
		{
			try
			{
				if (IsBlockingGameplayInput())
				{
					__result = false;
					return false;
				}
			}
			catch
			{
			}
			return true;
		}
	}

	public const string ModGuid = "carlosmmo.economy";

	public const string ModName = "Carlos MMO Economy";

	public const string ModVersion = "1.5.4";

	private const string MarketBenchPieceName = "piece_carlos_marketbench";

	private const string WalletKeyPrefix = "CarlosMMOEconomy_Balance_";

	private const string CurrencyNamePlural = "CriptoVikings";

	private const string CurrencyNameSingular = "CriptoViking";

	private static CarlosMMOEconomy _instance;

	private Harmony _harmony;

	private ConfigEntry<int> _startingCoins;

	private ConfigEntry<float> _marketBenchRange;

	private ConfigEntry<bool> _requireMarketBenchForShop;

	private ConfigEntry<KeyCode> _keyShowBalance;

	private ConfigEntry<KeyCode> _keyNextOffer;

	private ConfigEntry<KeyCode> _keyPrevOffer;

	private ConfigEntry<KeyCode> _keyBuyOffer;

	private ConfigEntry<KeyCode> _keyAddTestCoins;

	private ConfigEntry<KeyCode> _keyCloseMenu;

	private readonly List<ShopOffer> _offers = new List<ShopOffer>();

	private int _selectedOfferIndex = 0;

	private bool _marketBenchRegistered = false;

	private bool _marketMenuOpen = false;

	private Rect _marketWindowRect = new Rect(420f, 160f, 600f, 500f);

	private Vector2 _marketScroll = Vector2.zero;

	private GameObject _lastMarketBench;

	private bool _stylesInitialized = false;

	private bool _cursorWasVisible;

	private CursorLockMode _cursorPreviousLockMode = (CursorLockMode)1;

	private GUIStyle _windowStyle;

	private GUIStyle _labelStyle;

	private GUIStyle _titleStyle;

	private GUIStyle _buttonStyle;

	private GUIStyle _selectedButtonStyle;

	private GUIStyle _hintStyle;

	private GUIStyle _boxStyle;

	public static bool IsBlockingGameplayInput()
	{
		return (Object)(object)_instance != (Object)null && _instance._marketMenuOpen;
	}

	private void Awake()
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0025: Expected O, but got Unknown
		_instance = this;
		SetupConfig();
		SetupOffers();
		_harmony = new Harmony("carlosmmo.economy");
		_harmony.PatchAll();
		PrefabManager.OnVanillaPrefabsAvailable += RegisterMarketBench;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Carlos MMO Economy 1.5.4 carregado.");
	}

	private void OnDestroy()
	{
		PrefabManager.OnVanillaPrefabsAvailable -= RegisterMarketBench;
		RestoreMouseState();
		if (_harmony != null)
		{
			_harmony.UnpatchSelf();
		}
	}

	private void SetupConfig()
	{
		_startingCoins = ((BaseUnityPlugin)this).Config.Bind<int>("Economy", "StartingCoins", 100, "CriptoVikings iniciais para novo perfil local.");
		_marketBenchRange = ((BaseUnityPlugin)this).Config.Bind<float>("MarketBench", "UseRange", 4.25f, "Distância para usar a Bancada Mercado.");
		_requireMarketBenchForShop = ((BaseUnityPlugin)this).Config.Bind<bool>("MarketBench", "RequireBenchForShop", true, "Se true, a loja só funciona perto da Bancada Mercado.");
		_keyShowBalance = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "ShowBalance", (KeyCode)263, "Mostrar saldo atual.");
		_keyPrevOffer = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "PreviousOffer", (KeyCode)260, "Oferta anterior da loja.");
		_keyNextOffer = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "NextOffer", (KeyCode)262, "Próxima oferta da loja.");
		_keyBuyOffer = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "BuyOffer", (KeyCode)261, "Comprar oferta selecionada.");
		_keyAddTestCoins = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "AddTestCoins", (KeyCode)264, "Adicionar CriptoVikings de teste.");
		_keyCloseMenu = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Hotkeys", "CloseMenu", (KeyCode)265, "Fechar menu do mercado.");
	}

	private void SetupOffers()
	{
		_offers.Clear();
		AddOfferIfPrefabExists("Wood", "Madeira x100", 20, 100);
		AddOfferIfPrefabExists("Stone", "Pedra x100", 20, 100);
		AddOfferIfPrefabExists("Resin", "Resina x50", 25, 50);
		AddOfferIfPrefabExists("Coal", "Carvão x50", 30, 50);
		AddOfferIfPrefabExists("Flint", "Sílex x40", 28, 40);
		AddOfferIfPrefabExists("LeatherScraps", "Retalhos de couro x40", 35, 40);
		AddOfferIfPrefabExists("BoneFragments", "Fragmentos de osso x40", 35, 40);
		AddOfferIfPrefabExists("Feathers", "Penas x30", 45, 30);
		AddOfferIfPrefabExists("FineWood", "Madeira nobre x40", 50, 40);
		AddOfferIfPrefabExists("RoundLog", "Madeira do pinheiro x60", 45, 60);
		AddOfferIfPrefabExists("ElderBark", "Casca ancestral x30", 70, 30);
		AddOfferIfPrefabExists("AncientBark", "Madeira ancestral x30", 85, 30);
		AddOfferIfPrefabExists("CopperOre", "Minério de cobre x20", 70, 20);
		AddOfferIfPrefabExists("TinOre", "Minério de estanho x20", 60, 20);
		AddOfferIfPrefabExists("IronScrap", "Sucata de ferro x20", 120, 20);
		AddOfferIfPrefabExists("Silver", "Prata x12", 155, 12);
		AddOfferIfPrefabExists("BlackMetalScrap", "Sucata de metal negro x20", 180, 20);
		AddOfferIfPrefabExists("Copper", "Cobre x10", 80, 10);
		AddOfferIfPrefabExists("Bronze", "Bronze x10", 90, 10);
		AddOfferIfPrefabExists("Iron", "Ferro x10", 140, 10);
		AddOfferIfPrefabExists("BlackMetal", "Metal negro x10", 210, 10);
		AddOfferIfPrefabExists("SurtlingCore", "Núcleo de surtling x5", 90, 5);
		AddOfferIfPrefabExists("Guck", "Gosma x15", 55, 15);
		AddOfferIfPrefabExists("Obsidian", "Obsidiana x25", 80, 25);
		AddOfferIfPrefabExists("Crystal", "Cristal x20", 95, 20);
		AddOfferIfPrefabExists("FreezeGland", "Glândula congelante x10", 110, 10);
		AddOfferIfPrefabExists("Needle", "Agulhas x40", 95, 40);
		AddOfferIfPrefabExists("LinenThread", "Linha de linho x25", 100, 25);
		AddOfferIfPrefabExists("RoyalJelly", "Geleia real x20", 130, 20);
		AddOfferIfPrefabExists("YggdrasilWood", "Madeira Yggdrasil x25", 120, 25);
		AddOfferIfPrefabExists("Eitr", "Eitr refinado x10", 160, 10);
		AddOfferIfPrefabExists("CookedMeat", "Carne cozida x20", 40, 20);
		AddOfferIfPrefabExists("CookedDeerMeat", "Carne de cervo cozida x20", 45, 20);
		AddOfferIfPrefabExists("Sausages", "Salsichas x15", 70, 15);
		AddOfferIfPrefabExists("QueensJam", "Geleia da rainha x15", 55, 15);
		AddOfferIfPrefabExists("Bread", "Pão x15", 60, 15);
		AddOfferIfPrefabExists("WolfJerky", "Jerky de lobo x15", 75, 15);
		AddOfferIfPrefabExists("ArrowWood", "Flechas de madeira x100", 25, 100);
		AddOfferIfPrefabExists("ArrowFlint", "Flechas de sílex x100", 45, 100);
		AddOfferIfPrefabExists("ArrowIron", "Flechas de ferro x80", 95, 80);
		AddOfferIfPrefabExists("ArrowObsidian", "Flechas de obsidiana x80", 100, 80);
		AddOfferIfPrefabExists("ArrowNeedle", "Flechas de agulha x80", 125, 80);
		AddOfferIfPrefabExists("Coins", "CriptoVikings x100 (debug)", 1, 100);
	}

	private void AddOfferIfPrefabExists(string prefabName, string displayName, int price, int amount)
	{
		_offers.Add(new ShopOffer(prefabName, displayName, price, amount));
	}

	private void Update()
	{
		//IL_0047: 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_010c: Unknown result type (might be due to invalid IL or missing references)
		//IL_008e: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
		//IL_0148: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			if (_marketMenuOpen)
			{
				CloseMarketMenu();
			}
			return;
		}
		EnsureWalletInitialized();
		if (!_marketMenuOpen)
		{
			if (Input.GetKeyDown(_keyShowBalance.Value))
			{
				ShowBalance();
			}
			if (Input.GetKeyDown(_keyAddTestCoins.Value))
			{
				AddCoins(250, showMessage: true, "debug");
			}
			if (Input.GetKeyDown(_keyPrevOffer.Value))
			{
				SelectPreviousOffer();
			}
			if (Input.GetKeyDown(_keyNextOffer.Value))
			{
				SelectNextOffer();
			}
			if (Input.GetKeyDown(_keyBuyOffer.Value))
			{
				BuySelectedOffer();
			}
		}
		if (_marketMenuOpen)
		{
			ApplyMouseStateForMenu();
			if (Input.GetKeyDown((KeyCode)27) || Input.GetKeyDown(_keyCloseMenu.Value))
			{
				CloseMarketMenu();
			}
			else if ((Object)(object)_lastMarketBench == (Object)null || !IsNearSpecificBench(_lastMarketBench, ((Component)Player.m_localPlayer).transform.position, _marketBenchRange.Value + 1f))
			{
				CloseMarketMenu();
			}
		}
	}

	private void OnGUI()
	{
		//IL_003f: Unknown result type (might be due to invalid IL or missing references)
		//IL_004b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Expected O, but got Unknown
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Unknown result type (might be due to invalid IL or missing references)
		if (_marketMenuOpen)
		{
			if ((Object)(object)Player.m_localPlayer == (Object)null)
			{
				CloseMarketMenu();
				return;
			}
			EnsureGuiStyles();
			ApplyMouseStateForMenu();
			_marketWindowRect = GUI.Window(284915, _marketWindowRect, new WindowFunction(DrawMarketWindow), "Carlos MMO Mercado", _windowStyle);
		}
	}

	private void EnsureGuiStyles()
	{
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0026: Expected O, but got Unknown
		//IL_0031: Unknown result type (might be due to invalid IL or missing references)
		//IL_003b: Expected O, but got Unknown
		//IL_0046: Unknown result type (might be due to invalid IL or missing references)
		//IL_0050: Expected O, but got Unknown
		//IL_005b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0065: Expected O, but got Unknown
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_007a: Expected O, but got Unknown
		//IL_0085: Unknown result type (might be due to invalid IL or missing references)
		//IL_008f: Expected O, but got Unknown
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a4: Expected O, but got Unknown
		//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00bc: Expected O, but got Unknown
		//IL_00ea: 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_016e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0178: Expected O, but got Unknown
		//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Expected O, but got Unknown
		//IL_01d7: Unknown result type (might be due to invalid IL or missing references)
		//IL_0201: Unknown result type (might be due to invalid IL or missing references)
		//IL_022b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0270: Unknown result type (might be due to invalid IL or missing references)
		//IL_0285: Unknown result type (might be due to invalid IL or missing references)
		//IL_028f: Expected O, but got Unknown
		if (!_stylesInitialized)
		{
			_windowStyle = new GUIStyle(GUI.skin.window);
			_labelStyle = new GUIStyle(GUI.skin.label);
			_titleStyle = new GUIStyle(GUI.skin.label);
			_buttonStyle = new GUIStyle(GUI.skin.button);
			_selectedButtonStyle = new GUIStyle(GUI.skin.button);
			_hintStyle = new GUIStyle(GUI.skin.label);
			_boxStyle = new GUIStyle(GUI.skin.box);
			_windowStyle.padding = new RectOffset(14, 14, 28, 14);
			_titleStyle.fontSize = 20;
			_titleStyle.normal.textColor = new Color(0.96f, 0.96f, 0.98f, 1f);
			_labelStyle.fontSize = 14;
			_labelStyle.wordWrap = true;
			_labelStyle.normal.textColor = new Color(0.9f, 0.92f, 0.95f, 1f);
			_buttonStyle.fontSize = 13;
			_buttonStyle.wordWrap = true;
			_buttonStyle.alignment = (TextAnchor)3;
			_buttonStyle.padding = new RectOffset(10, 10, 7, 7);
			_selectedButtonStyle.fontSize = 13;
			_selectedButtonStyle.wordWrap = true;
			_selectedButtonStyle.alignment = (TextAnchor)3;
			_selectedButtonStyle.padding = new RectOffset(10, 10, 7, 7);
			_selectedButtonStyle.normal.textColor = new Color(0.8f, 0.96f, 1f, 1f);
			_selectedButtonStyle.hover.textColor = new Color(0.95f, 1f, 1f, 1f);
			_selectedButtonStyle.active.textColor = new Color(1f, 1f, 1f, 1f);
			_hintStyle.fontSize = 12;
			_hintStyle.wordWrap = true;
			_hintStyle.normal.textColor = new Color(0.72f, 0.78f, 0.84f, 1f);
			_boxStyle.padding = new RectOffset(8, 8, 8, 8);
			_stylesInitialized = true;
		}
	}

	private void DrawMarketWindow(int windowId)
	{
		//IL_0042: Unknown result type (might be due to invalid IL or missing references)
		//IL_0237: Unknown result type (might be due to invalid IL or missing references)
		//IL_023c: Unknown result type (might be due to invalid IL or missing references)
		//IL_023e: Unknown result type (might be due to invalid IL or missing references)
		//IL_035b: Unknown result type (might be due to invalid IL or missing references)
		int balance = GetBalance();
		ShopOffer selectedOffer = GetSelectedOffer();
		Rect val = default(Rect);
		((Rect)(ref val))..ctor(12f, 30f, ((Rect)(ref _marketWindowRect)).width - 24f, ((Rect)(ref _marketWindowRect)).height - 42f);
		GUILayout.BeginArea(val);
		GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
		GUILayout.Label("Bancada Mercado", _titleStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Space(4f);
		GUILayout.Label("Saldo atual de " + GetProfileDisplayName() + ": " + balance + " CriptoVikings", _labelStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Label("Tema: preto obsidiana + branco perolado", _hintStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Space(8f);
		GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
		if (GUILayout.Button("Anterior", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.Height(30f),
			GUILayout.Width(120f)
		}))
		{
			SelectPreviousOffer();
		}
		if (GUILayout.Button("Próxima", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.Height(30f),
			GUILayout.Width(120f)
		}))
		{
			SelectNextOffer();
		}
		if (GUILayout.Button("Comprar", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.Height(30f),
			GUILayout.Width(120f)
		}))
		{
			BuySelectedOffer();
		}
		if (GUILayout.Button("Fechar", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[2]
		{
			GUILayout.Height(30f),
			GUILayout.Width(120f)
		}))
		{
			CloseMarketMenu();
		}
		GUILayout.EndHorizontal();
		GUILayout.Space(10f);
		GUILayout.Label("Ofertas disponíveis:", _labelStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Space(4f);
		Rect rect = GUILayoutUtility.GetRect(((Rect)(ref val)).width - 8f, 265f, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.ExpandWidth(true) });
		DrawOfferScrollArea(rect);
		GUILayout.Space(8f);
		if (selectedOffer != null)
		{
			GUILayout.BeginVertical(_boxStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Selecionado: " + selectedOffer.DisplayName, _labelStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Quantidade: " + selectedOffer.Amount, _labelStyle, Array.Empty<GUILayoutOption>());
			GUILayout.Label("Preço: " + selectedOffer.Price + " CriptoVikings", _labelStyle, Array.Empty<GUILayoutOption>());
			GUILayout.EndVertical();
		}
		GUILayout.Space(10f);
		GUILayout.Label("Agora dá para rolar na barra com mouse e rodinha.", _hintStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Label("Enquanto o menu estiver aberto, o clique não deve mais fazer o personagem bater na bancada.", _hintStyle, Array.Empty<GUILayoutOption>());
		GUILayout.Label("Atalhos keypad: 7 saldo | 4 anterior | 6 próxima | 5 comprar | 8 debug | 9 fechar", _hintStyle, Array.Empty<GUILayoutOption>());
		GUILayout.EndVertical();
		GUILayout.EndArea();
		GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref _marketWindowRect)).width, 26f));
	}

	private void DrawOfferScrollArea(Rect outerRect)
	{
		//IL_0070: Unknown result type (might be due to invalid IL or missing references)
		//IL_0076: Invalid comparison between Unknown and I4
		//IL_007c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0121: 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_0128: Unknown result type (might be due to invalid IL or missing references)
		//IL_012b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0130: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
		//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
		float num = 34f;
		float num2 = 4f;
		float num3 = (float)_offers.Count * (num + num2) + 6f;
		if (num3 < ((Rect)(ref outerRect)).height)
		{
			num3 = ((Rect)(ref outerRect)).height - 1f;
		}
		Rect val = default(Rect);
		((Rect)(ref val))..ctor(0f, 0f, ((Rect)(ref outerRect)).width - 20f, num3);
		Event current = Event.current;
		if (current != null && (int)current.type == 6 && ((Rect)(ref outerRect)).Contains(current.mousePosition))
		{
			_marketScroll.y += current.delta.y * 22f;
			float num4 = Mathf.Max(0f, num3 - ((Rect)(ref outerRect)).height);
			if (_marketScroll.y < 0f)
			{
				_marketScroll.y = 0f;
			}
			if (_marketScroll.y > num4)
			{
				_marketScroll.y = num4;
			}
			current.Use();
		}
		_marketScroll = GUI.BeginScrollView(outerRect, _marketScroll, val, false, true);
		float num5 = 4f;
		Rect val3 = default(Rect);
		for (int i = 0; i < _offers.Count; i++)
		{
			ShopOffer shopOffer = _offers[i];
			string text = shopOffer.DisplayName + "  |  Preço: " + shopOffer.Price + " CriptoVikings";
			GUIStyle val2 = ((i == _selectedOfferIndex) ? _selectedButtonStyle : _buttonStyle);
			((Rect)(ref val3))..ctor(0f, num5, ((Rect)(ref val)).width - 6f, num);
			if (GUI.Button(val3, text, val2))
			{
				_selectedOfferIndex = i;
				ShowCurrentOffer();
			}
			num5 += num + num2;
		}
		GUI.EndScrollView();
	}

	private void ApplyMouseStateForMenu()
	{
		Cursor.visible = true;
		Cursor.lockState = (CursorLockMode)0;
	}

	private void RestoreMouseState()
	{
		//IL_000e: Unknown result type (might be due to invalid IL or missing references)
		Cursor.visible = _cursorWasVisible;
		Cursor.lockState = _cursorPreviousLockMode;
	}

	private void RegisterMarketBench()
	{
		//IL_0013: Unknown result type (might be due to invalid IL or missing references)
		//IL_0019: Expected O, but got Unknown
		//IL_008c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0092: Expected O, but got Unknown
		if (_marketBenchRegistered)
		{
			return;
		}
		try
		{
			PieceConfig val = new PieceConfig();
			val.Name = "Bancada Mercado";
			val.Description = "Mercado do Carlos MMO. Pressione E para abrir.";
			val.PieceTable = "Hammer";
			val.Category = "Crafting";
			val.CraftingStation = "piece_workbench";
			val.AddRequirement("Wood", 20, true);
			val.AddRequirement("Stone", 10, true);
			val.AddRequirement("Bronze", 2, true);
			CustomPiece val2 = new CustomPiece("piece_carlos_marketbench", "piece_workbench", val);
			try
			{
				ApplyMarketBenchVisual(val2.PiecePrefab);
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)("Falha ao aplicar visual da Bancada Mercado: " + ex.Message));
			}
			PieceManager.Instance.AddPiece(val2);
			_marketBenchRegistered = true;
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Bancada Mercado registrada com sucesso.");
		}
		catch (Exception ex2)
		{
			((BaseUnityPlugin)this).Logger.LogError((object)("Erro ao registrar Bancada Mercado: " + ex2));
		}
		finally
		{
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterMarketBench;
		}
	}

	private void ApplyMarketBenchVisual(GameObject piecePrefab)
	{
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0122: Expected O, but got Unknown
		//IL_01b6: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
		//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c0: Unknown result type (might be due to invalid IL or missing references)
		//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
		//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
		//IL_01db: Unknown result type (might be due to invalid IL or missing references)
		//IL_021c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0223: Unknown result type (might be due to invalid IL or missing references)
		//IL_020e: Unknown result type (might be due to invalid IL or missing references)
		//IL_0215: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)piecePrefab == (Object)null)
		{
			return;
		}
		Renderer[] componentsInChildren = piecePrefab.GetComponentsInChildren<Renderer>(true);
		if (componentsInChildren == null || componentsInChildren.Length == 0)
		{
			return;
		}
		Color val = default(Color);
		((Color)(ref val))..ctor(0.08f, 0.08f, 0.1f, 1f);
		Color val2 = default(Color);
		((Color)(ref val2))..ctor(0.92f, 0.93f, 0.96f, 1f);
		Color val3 = default(Color);
		((Color)(ref val3))..ctor(0.68f, 0.72f, 0.78f, 1f);
		Color val4 = default(Color);
		((Color)(ref val4))..ctor(0.85f, 0.9f, 1f, 1f);
		foreach (Renderer val5 in componentsInChildren)
		{
			if ((Object)(object)val5 == (Object)null)
			{
				continue;
			}
			Material[] sharedMaterials = val5.sharedMaterials;
			if (sharedMaterials == null || sharedMaterials.Length == 0)
			{
				continue;
			}
			Material[] array = (Material[])(object)new Material[sharedMaterials.Length];
			for (int j = 0; j < sharedMaterials.Length; j++)
			{
				Material val6 = sharedMaterials[j];
				if ((Object)(object)val6 == (Object)null)
				{
					array[j] = null;
					continue;
				}
				Material val7 = new Material(val6);
				string text = ((((Object)((Component)val5).gameObject).name ?? string.Empty) + " " + (((Object)val6).name ?? string.Empty)).ToLowerInvariant();
				bool flag = text.Contains("metal") || text.Contains("iron") || text.Contains("bronze") || text.Contains("nail") || text.Contains("trim") || text.Contains("detail");
				Color color = (flag ? val2 : val);
				Color val8 = (flag ? val3 : val);
				TrySetColor(val7, "_Color", color);
				TrySetColor(val7, "_BaseColor", color);
				if (val7.HasProperty("_EmissionColor"))
				{
					val7.EnableKeyword("_EMISSION");
					val7.SetColor("_EmissionColor", flag ? (val4 * 0.12f) : (val8 * 0.03f));
				}
				if (val7.HasProperty("_Glossiness"))
				{
					val7.SetFloat("_Glossiness", flag ? 0.72f : 0.38f);
				}
				if (val7.HasProperty("_Smoothness"))
				{
					val7.SetFloat("_Smoothness", flag ? 0.72f : 0.38f);
				}
				if (val7.HasProperty("_Metallic"))
				{
					val7.SetFloat("_Metallic", flag ? 0.2f : 0.06f);
				}
				array[j] = val7;
			}
			val5.materials = array;
		}
	}

	private void TrySetColor(Material mat, string propertyName, Color color)
	{
		//IL_001b: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)mat != (Object)null && mat.HasProperty(propertyName))
		{
			mat.SetColor(propertyName, color);
		}
	}

	private void EnsureWalletInitialized()
	{
		string walletKey = GetWalletKey();
		if (!PlayerPrefs.HasKey(walletKey))
		{
			PlayerPrefs.SetInt(walletKey, _startingCoins.Value);
			PlayerPrefs.Save();
			if ((Object)(object)Player.m_localPlayer != (Object)null)
			{
				((Character)Player.m_localPlayer).Message((MessageType)1, "[Carlos MMO] Carteira CriptoVikings criada para " + GetProfileDisplayName() + ": " + _startingCoins.Value + " CriptoVikings.", 0, (Sprite)null);
			}
		}
	}

	private string GetWalletKey()
	{
		string text = "default";
		try
		{
			if ((Object)(object)Game.instance != (Object)null && Game.instance.GetPlayerProfile() != null)
			{
				string name = Game.instance.GetPlayerProfile().GetName();
				if (!string.IsNullOrEmpty(name))
				{
					text = name;
				}
			}
		}
		catch
		{
		}
		return "CarlosMMOEconomy_Balance_" + text;
	}

	private string GetProfileDisplayName()
	{
		string result = "Desconhecido";
		try
		{
			if ((Object)(object)Game.instance != (Object)null && Game.instance.GetPlayerProfile() != null)
			{
				string name = Game.instance.GetPlayerProfile().GetName();
				if (!string.IsNullOrEmpty(name))
				{
					result = name;
				}
			}
		}
		catch
		{
		}
		return result;
	}

	private int GetBalance()
	{
		return PlayerPrefs.GetInt(GetWalletKey(), _startingCoins.Value);
	}

	private void SetBalance(int value)
	{
		if (value < 0)
		{
			value = 0;
		}
		PlayerPrefs.SetInt(GetWalletKey(), value);
		PlayerPrefs.Save();
	}

	private void AddCoins(int amount, bool showMessage, string reason)
	{
		int balance = GetBalance();
		int balance2 = balance + amount;
		SetBalance(balance2);
		if (showMessage && (Object)(object)Player.m_localPlayer != (Object)null)
		{
			((Character)Player.m_localPlayer).Message((MessageType)1, "[Carlos MMO] +" + amount + " " + GetCurrencyName(amount) + BuildReasonSuffix(reason) + " | Saldo de " + GetProfileDisplayName() + ": " + balance2 + " CriptoVikings", 0, (Sprite)null);
		}
	}

	private bool SpendCoins(int amount, bool showMessage)
	{
		int balance = GetBalance();
		if (balance < amount)
		{
			if (showMessage && (Object)(object)Player.m_localPlayer != (Object)null)
			{
				((Character)Player.m_localPlayer).Message((MessageType)1, "[Carlos MMO] CriptoVikings insuficientes para " + GetProfileDisplayName() + ". Saldo: " + balance + " CriptoVikings", 0, (Sprite)null);
			}
			return false;
		}
		int balance2 = balance - amount;
		SetBalance(balance2);
		if (showMessage && (Object)(object)Player.m_localPlayer != (Object)null)
		{
			((Character)Player.m_localPlayer).Message((MessageType)1, "[Carlos MMO] -" + amount + " " + GetCurrencyName(amount) + " | Saldo de " + GetProfileDisplayName() + ": " + balance2 + " CriptoVikings", 0, (Sprite)null);
		}
		return true;
	}

	private string GetCurrencyName(int amount)
	{
		return (amount == 1) ? "CriptoViking" : "CriptoVikings";
	}

	private string BuildReasonSuffix(string reason)
	{
		if (string.IsNullOrEmpty(reason))
		{
			return string.Empty;
		}
		return " (" + reason + ")";
	}

	private void ShowBalance()
	{
		if (!((Object)(object)Player.m_localPlayer == (Object)null))
		{
			int balance = GetBalance();
			ShopOffer selectedOffer = GetSelectedOffer();
			string text = "[Carlos MMO] Saldo de " + GetProfileDisplayName() + ": " + balance + " CriptoVikings";
			if (selectedOffer != null)
			{
				text = text + " | Oferta: " + selectedOffer.DisplayName + " - " + selectedOffer.Price + " CriptoVikings";
			}
			((Character)Player.m_localPlayer).Message((MessageType)1, text, 0, (Sprite)null);
		}
	}

	private void SelectPreviousOffer()
	{
		if (_offers.Count != 0)
		{
			_selectedOfferIndex--;
			if (_selectedOfferIndex < 0)
			{
				_selectedOfferIndex = _offers.Count - 1;
			}
			ShowCurrentOffer();
			SnapScrollToSelection();
		}
	}

	private void SelectNextOffer()
	{
		if (_offers.Count != 0)
		{
			_selectedOfferIndex++;
			if (_selectedOfferIndex >= _offers.Count)
			{
				_selectedOfferIndex = 0;
			}
			ShowCurrentOffer();
			SnapScrollToSelection();
		}
	}

	private void SnapScrollToSelection()
	{
		float num = 38f;
		float num2 = 265f;
		float num3 = (float)_selectedOfferIndex * num;
		float num4 = num3 + num;
		if (num3 < _marketScroll.y)
		{
			_marketScroll.y = num3;
		}
		else if (num4 > _marketScroll.y + num2)
		{
			_marketScroll.y = num4 - num2;
		}
		if (_marketScroll.y < 0f)
		{
			_marketScroll.y = 0f;
		}
	}

	private ShopOffer GetSelectedOffer()
	{
		if (_offers.Count == 0)
		{
			return null;
		}
		if (_selectedOfferIndex < 0 || _selectedOfferIndex >= _offers.Count)
		{
			_selectedOfferIndex = 0;
		}
		return _offers[_selectedOfferIndex];
	}

	private void ShowCurrentOffer()
	{
		if (!((Object)(object)Player.m_localPlayer == (Object)null))
		{
			ShopOffer selectedOffer = GetSelectedOffer();
			if (selectedOffer != null)
			{
				((Character)Player.m_localPlayer).Message((MessageType)1, "[Carlos MMO Loja] " + selectedOffer.DisplayName + " | Preço: " + selectedOffer.Price + " CriptoVikings", 0, (Sprite)null);
			}
		}
	}

	private void BuySelectedOffer()
	{
		//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)Player.m_localPlayer == (Object)null)
		{
			return;
		}
		ShopOffer selectedOffer = GetSelectedOffer();
		if (selectedOffer == null)
		{
			((Character)Player.m_localPlayer).Message((MessageType)1, "[Carlos MMO Loja] Nenhuma oferta disponível.", 0, (Sprite)null);
		}
		else if (_requireMarketBenchForShop.Value && !IsNearMarketBench(((Component)Player.m_localPlayer).transform.position, _marketBenchRange.Value + 0.75f))
		{
			((Character)Player.m_localPlayer).Message((MessageType)1, "[Carlos MMO Loja] Você precisa estar perto da Bancada Mercado.", 0, (Sprite)null);
		}
		else if (SpendCoins(selectedOffer.Price, showMessage: true))
		{
			if (!GiveItemToPlayer(selectedOffer.PrefabName, selectedOffer.Amount))
			{
				AddCoins(selectedOffer.Price, showMessage: false, string.Empty);
				((Character)Player.m_localPlayer).Message((MessageType)1, "[Carlos MMO Loja] Falha ao entregar item: " + selectedOffer.PrefabName, 0, (Sprite)null);
			}
			else
			{
				((Character)Player.m_localPlayer).Message((MessageType)1, "[Carlos MMO Loja] Compra realizada por " + GetProfileDisplayName() + ": " + selectedOffer.DisplayName, 0, (Sprite)null);
			}
		}
	}

	private bool GiveItemToPlayer(string prefabName, int amount)
	{
		//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
		//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ef: 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)
		if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ObjectDB.instance == (Object)null)
		{
			return false;
		}
		GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName);
		if ((Object)(object)itemPrefab == (Object)null)
		{
			((BaseUnityPlugin)this).Logger.LogWarning((object)("Prefab não encontrado na loja: " + prefabName));
			return false;
		}
		Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
		if (inventory == null)
		{
			return false;
		}
		int num = amount;
		while (num > 0)
		{
			int num2 = ((num > 100) ? 100 : num);
			ItemData val = inventory.AddItem(prefabName, num2, 1, 0, 0L, string.Empty, false);
			if (val == null)
			{
				Vector3 val2 = ((Component)Player.m_localPlayer).transform.position + ((Component)Player.m_localPlayer).transform.forward * 1.5f + Vector3.up;
				GameObject val3 = Object.Instantiate<GameObject>(itemPrefab, val2, Quaternion.identity);
				ItemDrop component = val3.GetComponent<ItemDrop>();
				if ((Object)(object)component != (Object)null)
				{
					component.m_itemData.m_stack = num2;
				}
			}
			num -= num2;
		}
		return true;
	}

	private bool IsNearMarketBench(Vector3 center, float range)
	{
		//IL_0095: Unknown result type (might be due to invalid IL or missing references)
		//IL_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_009b: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
		Piece[] array = Object.FindObjectsOfType<Piece>();
		if (array == null || array.Length == 0)
		{
			return false;
		}
		float num = range * range;
		foreach (Piece val in array)
		{
			if ((Object)(object)val == (Object)null)
			{
				continue;
			}
			GameObject gameObject = ((Component)val).gameObject;
			if ((Object)(object)gameObject == (Object)null)
			{
				continue;
			}
			string name = ((Object)gameObject).name;
			if (!string.IsNullOrEmpty(name) && name.StartsWith("piece_carlos_marketbench", StringComparison.Ordinal))
			{
				Vector3 val2 = gameObject.transform.position - center;
				float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
				if (sqrMagnitude <= num)
				{
					return true;
				}
			}
		}
		return false;
	}

	private bool IsNearSpecificBench(GameObject bench, Vector3 center, float range)
	{
		//IL_0017: Unknown result type (might be due to invalid IL or missing references)
		//IL_001c: Unknown result type (might be due to invalid IL or missing references)
		//IL_001d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0022: Unknown result type (might be due to invalid IL or missing references)
		if ((Object)(object)bench == (Object)null)
		{
			return false;
		}
		Vector3 val = bench.transform.position - center;
		float sqrMagnitude = ((Vector3)(ref val)).sqrMagnitude;
		return sqrMagnitude <= range * range;
	}

	private bool IsMarketBenchObject(GameObject obj)
	{
		if ((Object)(object)obj == (Object)null)
		{
			return false;
		}
		string name = ((Object)obj).name;
		if (string.IsNullOrEmpty(name))
		{
			return false;
		}
		return name.StartsWith("piece_carlos_marketbench", StringComparison.Ordinal);
	}

	private void ToggleMarketMenu(GameObject bench)
	{
		//IL_0040: Unknown result type (might be due to invalid IL or missing references)
		//IL_0045: Unknown result type (might be due to invalid IL or missing references)
		//IL_0059: Unknown result type (might be due to invalid IL or missing references)
		//IL_005e: Unknown result type (might be due to invalid IL or missing references)
		if (!((Object)(object)bench == (Object)null))
		{
			if (_marketMenuOpen && (Object)(object)_lastMarketBench == (Object)(object)bench)
			{
				CloseMarketMenu();
				return;
			}
			_cursorWasVisible = Cursor.visible;
			_cursorPreviousLockMode = Cursor.lockState;
			_lastMarketBench = bench;
			_marketMenuOpen = true;
			_marketScroll = Vector2.zero;
			ApplyMouseStateForMenu();
			ShowCurrentOffer();
		}
	}

	private void CloseMarketMenu()
	{
		_marketMenuOpen = false;
		_lastMarketBench = null;
		RestoreMouseState();
	}
}