Decompiled source of Pit Reparador v1.2.0

PitReparador.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("Pit Reparador")]
[assembly: AssemblyDescription("Pit Reparador: Reparo automático de todos os itens ao interagir com bancadas de trabalho e forjas no Valheim.")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Amigos do Pit")]
[assembly: AssemblyProduct("Pit Reparador")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("C8407B18-2940-4A51-B2C5-63F01C9A4B82")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace PitReparador
{
	[BepInPlugin("org.bepinex.plugins.pit_reparador", "Pit Reparador", "1.2.0")]
	[BepInIncompatibility("Tekla_AutoRepair")]
	public class PitReparadorPlugin : BaseUnityPlugin
	{
		public const string ModGUID = "org.bepinex.plugins.pit_reparador";

		public const string ModName = "Pit Reparador";

		public const string ModVersion = "1.2.0";

		public const string ModAuthor = "Amigos do Pit";

		internal static ManualLogSource Log = null;

		private Harmony _harmony;

		public static ConfigEntry<bool> ModEnabled = null;

		public static ConfigEntry<bool> AutoRepairOnInteract = null;

		public static ConfigEntry<bool> RepairAllOnClick = null;

		public static ConfigEntry<bool> ShowNotification = null;

		public static ConfigEntry<bool> PlayEffects = null;

		public static ConfigEntry<string> CustomMessage = null;

		public static ConfigEntry<bool> HammerAreaRepairEnabled = null;

		public static ConfigEntry<float> HammerAreaRepairRadius = null;

		public static ConfigEntry<int> HammerAreaRepairMaxPieces = null;

		public static ConfigEntry<bool> HammerAreaRepairRequireStation = null;

		public static ConfigEntry<bool> HammerAreaRepairAnyStationInRange = null;

		public static ConfigEntry<bool> HammerAreaRepairRequireWardAccess = null;

		public static ConfigEntry<bool> HammerAreaRepairStaminaDrainPerPiece = null;

		public static ConfigEntry<bool> HammerAreaRepairDurabilityDrainPerPiece = null;

		public static ConfigEntry<bool> HammerAreaRepairShowEffect = null;

		public static ConfigEntry<bool> HammerAreaRepairNotification = null;

		public static ConfigEntry<string> HammerCustomMessage = null;

		internal static bool SuppressMessages = false;

		private static readonly EffectList EmptyEffectList = new EffectList
		{
			m_effectPrefabs = (EffectData[])(object)new EffectData[0]
		};

		private static Func<InventoryGui, bool>? _haveRepairableItems;

		private static Action<InventoryGui>? _repairOneItem;

		private static Action<InventoryGui>? _updateRepair;

		private static Action<InventoryGui>? _updateCraftingPanel;

		private void Awake()
		{
			//IL_011d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0127: Expected O, but got Unknown
			//IL_0157: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Expected O, but got Unknown
			//IL_0275: Unknown result type (might be due to invalid IL or missing references)
			//IL_027f: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "ModEnabled", true, "Habilita ou desabilita o mod Pit Reparador.");
			AutoRepairOnInteract = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "AutoRepairOnInteract", true, "Repara automaticamente todos os itens ao abrir/interagir com bancadas de trabalho.");
			RepairAllOnClick = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "RepairAllOnClick", true, "Repara todos os itens de uma vez ao clicar no botão do martelo de reparo na bancada.");
			ShowNotification = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - UI", "ShowNotification", true, "Exibe uma notificação na tela com a quantidade de itens de inventário reparados.");
			PlayEffects = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Audio & Effects", "PlayEffects", true, "Toca o som e efeito visual de martelada da bancada uma única vez ao reparar itens.");
			CustomMessage = ((BaseUnityPlugin)this).Config.Bind<string>("2 - UI", "CustomMessage", "", "Mensagem personalizada ao reparar itens no inventário (use {0} para a quantidade). Deixe vazio para usar a tradução automática.");
			HammerAreaRepairEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Hammer Area Repair", "HammerAreaRepairEnabled", true, "Habilita o reparo de construções em área ao utilizar o martelo de construção.");
			HammerAreaRepairRadius = ((BaseUnityPlugin)this).Config.Bind<float>("4 - Hammer Area Repair", "HammerAreaRepairRadius", 30f, new ConfigDescription("Raio da área de reparo em metros (alcance ajustável de até 50m ou mais).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 100f), Array.Empty<object>()));
			HammerAreaRepairMaxPieces = ((BaseUnityPlugin)this).Config.Bind<int>("4 - Hammer Area Repair", "HammerAreaRepairMaxPieces", 250, new ConfigDescription("Limite máximo de peças/estruturas a serem reparadas por golpe.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 1000), Array.Empty<object>()));
			HammerAreaRepairRequireStation = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Hammer Area Repair", "HammerAreaRepairRequireStation", true, "Exige que a peça a ser reparada esteja dentro do alcance da bancada de construção.");
			HammerAreaRepairAnyStationInRange = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Hammer Area Repair", "HammerAreaRepairAnyStationInRange", true, "Se ativado, permite reparar qualquer tipo de construção (madeira, pedra, grausten, metal, ashlands, deep north) se houver qualquer bancada válida no alcance da base, sem exigir ter bancada, cortador de pedra e forja negra no mesmo local.");
			HammerAreaRepairRequireWardAccess = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Hammer Area Repair", "HammerAreaRepairRequireWardAccess", true, "Respeita a proteção de Wards (PrivateArea), impedindo reparar estruturas em áreas protegidas sem permissão.");
			HammerAreaRepairStaminaDrainPerPiece = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Hammer Area Repair", "HammerAreaRepairStaminaDrainPerPiece", false, "Se ativado, multiplica o consumo de estamina pela quantidade de peças reparadas. Se desativado, consome a estamina de 1 único golpe.");
			HammerAreaRepairDurabilityDrainPerPiece = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Hammer Area Repair", "HammerAreaRepairDurabilityDrainPerPiece", false, "Se ativado, multiplica a perda de durabilidade do martelo pela quantidade de peças reparadas. Se desativado, consome a durabilidade de 1 único golpe.");
			HammerAreaRepairShowEffect = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Hammer Area Repair", "HammerAreaRepairShowEffect", true, "Reproduz efeito visual e sonoro do martelo ao reparar as peças da área.");
			HammerAreaRepairNotification = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - Hammer Area Repair", "HammerAreaRepairNotification", true, "Exibe notificação na tela indicando a quantidade de peças de construção reparadas.");
			HammerCustomMessage = ((BaseUnityPlugin)this).Config.Bind<string>("4 - Hammer Area Repair", "HammerCustomMessage", "", "Mensagem personalizada ao reparar construções com martelo (use {0} para a quantidade). Deixe vazio para usar a mensagem padrão.");
			InitDelegates();
			_harmony = new Harmony("org.bepinex.plugins.pit_reparador");
			_harmony.PatchAll(Assembly.GetExecutingAssembly());
			Log.LogInfo((object)"[Pit Reparador] v1.2.0 inicializado com sucesso! Reparo automático de inventário e Reparo em Área com martelo ativados.");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}

		private static void InitDelegates()
		{
			try
			{
				MethodInfo methodInfo = AccessTools.Method(typeof(InventoryGui), "HaveRepairableItems", (Type[])null, (Type[])null);
				if (methodInfo != null)
				{
					if (methodInfo.GetParameters().Length == 1)
					{
						Func<InventoryGui, bool, bool> del = AccessTools.MethodDelegate<Func<InventoryGui, bool, bool>>(methodInfo, (object)null, true);
						_haveRepairableItems = (InventoryGui gui) => del(gui, arg2: false);
					}
					else
					{
						_haveRepairableItems = AccessTools.MethodDelegate<Func<InventoryGui, bool>>(methodInfo, (object)null, true);
					}
				}
				MethodInfo methodInfo2 = AccessTools.Method(typeof(InventoryGui), "RepairOneItem", (Type[])null, (Type[])null);
				if (methodInfo2 != null)
				{
					if (methodInfo2.GetParameters().Length == 1)
					{
						Action<InventoryGui, bool> del2 = AccessTools.MethodDelegate<Action<InventoryGui, bool>>(methodInfo2, (object)null, true);
						_repairOneItem = delegate(InventoryGui gui)
						{
							del2(gui, arg2: false);
						};
					}
					else
					{
						_repairOneItem = AccessTools.MethodDelegate<Action<InventoryGui>>(methodInfo2, (object)null, true);
					}
				}
				MethodInfo methodInfo3 = AccessTools.Method(typeof(InventoryGui), "UpdateRepair", (Type[])null, (Type[])null);
				if (methodInfo3 != null)
				{
					if (methodInfo3.GetParameters().Length == 1)
					{
						Action<InventoryGui, bool> del3 = AccessTools.MethodDelegate<Action<InventoryGui, bool>>(methodInfo3, (object)null, true);
						_updateRepair = delegate(InventoryGui gui)
						{
							del3(gui, arg2: false);
						};
					}
					else
					{
						_updateRepair = AccessTools.MethodDelegate<Action<InventoryGui>>(methodInfo3, (object)null, true);
					}
				}
				MethodInfo methodInfo4 = AccessTools.Method(typeof(InventoryGui), "UpdateCraftingPanel", (Type[])null, (Type[])null);
				if (!(methodInfo4 != null))
				{
					return;
				}
				if (methodInfo4.GetParameters().Length == 1)
				{
					Action<InventoryGui, bool> del4 = AccessTools.MethodDelegate<Action<InventoryGui, bool>>(methodInfo4, (object)null, true);
					_updateCraftingPanel = delegate(InventoryGui gui)
					{
						del4(gui, arg2: false);
					};
				}
				else
				{
					_updateCraftingPanel = AccessTools.MethodDelegate<Action<InventoryGui>>(methodInfo4, (object)null, true);
				}
			}
			catch (Exception arg)
			{
				Log.LogError((object)string.Format("[{0}] Erro ao inicializar delegados de reflexão: {1}", "Pit Reparador", arg));
			}
		}

		private static float GetInventoryTotalDurability(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return 0f;
			}
			Inventory inventory = ((Humanoid)player).GetInventory();
			if (inventory == null)
			{
				return 0f;
			}
			List<ItemData> allItems = inventory.GetAllItems();
			if (allItems == null)
			{
				return 0f;
			}
			float num = 0f;
			for (int i = 0; i < allItems.Count; i++)
			{
				ItemData val = allItems[i];
				if (val != null && val.m_shared != null && val.m_shared.m_useDurability)
				{
					num += val.m_durability;
				}
			}
			return num;
		}

		public static void ExecuteRepairAll(CraftingStation? station, bool isManualClick = false)
		{
			//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_01f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fe: Unknown result type (might be due to invalid IL or missing references)
			if (!ModEnabled.Value)
			{
				return;
			}
			Player localPlayer = Player.m_localPlayer;
			if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead())
			{
				return;
			}
			InventoryGui instance = InventoryGui.instance;
			if ((Object)(object)instance == (Object)null)
			{
				return;
			}
			if (_haveRepairableItems == null || _repairOneItem == null)
			{
				Log.LogWarning((object)"[Pit Reparador] Métodos de reparo de InventoryGui indisponíveis.");
				return;
			}
			if (!_haveRepairableItems(instance))
			{
				if (!isManualClick)
				{
					return;
				}
				try
				{
					_updateRepair?.Invoke(instance);
					_updateCraftingPanel?.Invoke(instance);
					return;
				}
				catch
				{
					return;
				}
			}
			int num = 0;
			Inventory inventory = ((Humanoid)localPlayer).GetInventory();
			int valueOrDefault = ((inventory == null) ? ((int?)null) : inventory.GetAllItems()?.Count).GetValueOrDefault();
			int num2 = Math.Max(100, valueOrDefault + 10);
			int num3 = 0;
			EffectList repairItemDoneEffects = (((Object)(object)station != (Object)null) ? station.m_repairItemDoneEffects : null);
			try
			{
				SuppressMessages = true;
				if ((Object)(object)station != (Object)null)
				{
					station.m_repairItemDoneEffects = EmptyEffectList;
				}
				float num4 = GetInventoryTotalDurability(localPlayer);
				while (num3 < num2 && _haveRepairableItems(instance))
				{
					num3++;
					_repairOneItem(instance);
					float inventoryTotalDurability = GetInventoryTotalDurability(localPlayer);
					if (!(inventoryTotalDurability <= num4 + 0.0001f))
					{
						num4 = inventoryTotalDurability;
						num++;
						continue;
					}
					break;
				}
			}
			catch (Exception arg)
			{
				Log.LogError((object)string.Format("[{0}] Ocorreu um erro durante o reparo de itens: {1}", "Pit Reparador", arg));
			}
			finally
			{
				if ((Object)(object)station != (Object)null)
				{
					station.m_repairItemDoneEffects = repairItemDoneEffects;
				}
				SuppressMessages = false;
			}
			try
			{
				_updateRepair?.Invoke(instance);
				_updateCraftingPanel?.Invoke(instance);
			}
			catch
			{
			}
			if (num > 0)
			{
				if (PlayEffects.Value && (Object)(object)station != (Object)null && station.m_repairItemDoneEffects != null)
				{
					station.m_repairItemDoneEffects.Create(((Component)station).transform.position, Quaternion.identity, (Transform)null, 1f, -1, default(ZDOID));
				}
				if (ShowNotification.Value)
				{
					string repairNotification = GetRepairNotification(num);
					((Character)localPlayer).Message((MessageType)2, repairNotification, 0, (Sprite)null, false);
				}
				string text = (((Object)(object)station != (Object)null) ? station.m_name : "Bancada");
				Log.LogInfo((object)string.Format("[{0}] {1} item(ns) reparado(s) com sucesso na bancada '{2}' (Manual: {3}).", "Pit Reparador", num, text, isManualClick));
			}
		}

		private static string GetRepairNotification(int count)
		{
			if (!string.IsNullOrEmpty(CustomMessage.Value))
			{
				return string.Format(CustomMessage.Value, count);
			}
			if ((Localization.instance != null && Localization.instance.GetSelectedLanguage() == "Portuguese_Brazilian") || CultureInfo.CurrentUICulture.TwoLetterISOLanguageName.Equals("pt", StringComparison.OrdinalIgnoreCase))
			{
				if (count != 1)
				{
					return $"{count} itens reparados!";
				}
				return "1 item reparado!";
			}
			if (count != 1)
			{
				return $"{count} items repaired!";
			}
			return "1 item repaired!";
		}

		private static bool HasAnyBuildStationInRange(Vector3 pos)
		{
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			if (CraftingStation.m_allStations == null)
			{
				return false;
			}
			for (int i = 0; i < CraftingStation.m_allStations.Count; i++)
			{
				CraftingStation val = CraftingStation.m_allStations[i];
				if ((Object)(object)val != (Object)null)
				{
					float stationBuildRange = val.GetStationBuildRange();
					if (Vector3.Distance(((Component)val).transform.position, pos) <= stationBuildRange)
					{
						return true;
					}
				}
			}
			return false;
		}

		private static bool HasRequiredStation(Piece piece, Vector3 piecePos, Vector3 playerPos, bool anyStation)
		{
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)piece == (Object)null || (Object)(object)piece.m_craftingStation == (Object)null)
			{
				return true;
			}
			string name = piece.m_craftingStation.m_name;
			if ((Object)(object)CraftingStation.HaveBuildStationInRange(name, piecePos) != (Object)null || (Object)(object)CraftingStation.HaveBuildStationInRange(name, playerPos) != (Object)null)
			{
				return true;
			}
			if (anyStation && (HasAnyBuildStationInRange(playerPos) || HasAnyBuildStationInRange(piecePos)))
			{
				return true;
			}
			return false;
		}

		private static bool TryRepairWearNTear(WearNTear wnt, Vector3 playerPos, bool requireWard, bool requireStation, bool anyStation, bool noPlacementCost, bool noWorkbenchKey)
		{
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)wnt == (Object)null || (Object)(object)wnt.m_nview == (Object)null || !wnt.m_nview.IsValid())
			{
				return false;
			}
			Vector3 position = ((Component)wnt).transform.position;
			if (requireWard && !PrivateArea.CheckAccess(position, 0f, true, false))
			{
				return false;
			}
			bool num = wnt.m_nview.GetZDO().GetFloat(ZDOVars.s_health, wnt.m_health) < wnt.m_health - 0.01f;
			bool flag = wnt.m_ashMaterialValue > 0.01f;
			if (!num && !flag)
			{
				return false;
			}
			if (requireStation && !noPlacementCost && !noWorkbenchKey && !HasRequiredStation(wnt.m_piece ?? ((Component)wnt).GetComponent<Piece>() ?? ((Component)wnt).GetComponentInParent<Piece>() ?? ((Component)wnt).GetComponentInChildren<Piece>(), position, playerPos, anyStation))
			{
				return false;
			}
			wnt.m_lastRepair = 0f;
			if (!wnt.m_nview.IsOwner())
			{
				wnt.m_nview.ClaimOwnership();
			}
			wnt.m_nview.GetZDO().Set(ZDOVars.s_health, wnt.m_health);
			wnt.m_nview.InvokeRPC(ZNetView.Everybody, "RPC_HealthChanged", new object[1] { wnt.m_health });
			wnt.SetAshlandsMaterialValue(0f);
			wnt.m_ashTimer = 0f;
			wnt.m_ashDamageTime = 0f;
			wnt.m_burnDamageTime = 0f;
			wnt.m_lastBurnDamageTime = 0f;
			wnt.m_snowDamageTimer = 0f;
			wnt.UpdateVisual(true);
			return true;
		}

		public static void ExecuteHammerAreaRepair(Player player, ItemData toolItem, Piece repairPiece)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01eb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f0: 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_011f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0125: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_017f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_025a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0301: Unknown result type (might be due to invalid IL or missing references)
			//IL_030c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0319: Unknown result type (might be due to invalid IL or missing references)
			//IL_0343: Unknown result type (might be due to invalid IL or missing references)
			//IL_0348: Unknown result type (might be due to invalid IL or missing references)
			//IL_0355: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null || ((Character)player).IsDead() || !((Character)player).InPlaceMode() || toolItem == null || toolItem.m_shared == null)
			{
				return;
			}
			Piece hoveringPiece = player.GetHoveringPiece();
			if ((Object)(object)hoveringPiece != (Object)null && HammerAreaRepairRequireWardAccess.Value && !PrivateArea.CheckAccess(((Component)hoveringPiece).transform.position, 0f, true, false))
			{
				return;
			}
			Vector3 val = (((Object)(object)hoveringPiece != (Object)null) ? ((Component)hoveringPiece).transform.position : ((Component)player).transform.position);
			float num = Mathf.Clamp(HammerAreaRepairRadius.Value, 1f, 150f);
			float num2 = num * num;
			int num3 = Math.Max(1, HammerAreaRepairMaxPieces.Value);
			HashSet<WearNTear> hashSet = new HashSet<WearNTear>();
			if ((Object)(object)hoveringPiece != (Object)null)
			{
				WearNTear val2 = ((Component)hoveringPiece).GetComponent<WearNTear>() ?? ((Component)hoveringPiece).GetComponentInChildren<WearNTear>() ?? ((Component)hoveringPiece).GetComponentInParent<WearNTear>();
				if ((Object)(object)val2 != (Object)null)
				{
					hashSet.Add(val2);
				}
			}
			List<WearNTear> allInstances = WearNTear.GetAllInstances();
			Vector3 val4;
			if (allInstances != null)
			{
				for (int i = 0; i < allInstances.Count; i++)
				{
					WearNTear val3 = allInstances[i];
					if ((Object)(object)val3 != (Object)null)
					{
						val4 = ((Component)val3).transform.position - val;
						if (((Vector3)(ref val4)).sqrMagnitude <= num2)
						{
							hashSet.Add(val3);
						}
					}
				}
			}
			if (Piece.s_allPieces != null)
			{
				for (int j = 0; j < Piece.s_allPieces.Count; j++)
				{
					Piece val5 = Piece.s_allPieces[j];
					if (!((Object)(object)val5 != (Object)null))
					{
						continue;
					}
					val4 = ((Component)val5).transform.position - val;
					if (((Vector3)(ref val4)).sqrMagnitude <= num2)
					{
						WearNTear val6 = ((Component)val5).GetComponent<WearNTear>() ?? ((Component)val5).GetComponentInChildren<WearNTear>() ?? ((Component)val5).GetComponentInParent<WearNTear>();
						if ((Object)(object)val6 != (Object)null)
						{
							hashSet.Add(val6);
						}
					}
				}
			}
			if (hashSet.Count == 0)
			{
				return;
			}
			int num4 = 0;
			Vector3 position = ((Component)player).transform.position;
			bool value = HammerAreaRepairRequireStation.Value;
			bool value2 = HammerAreaRepairAnyStationInRange.Value;
			bool value3 = HammerAreaRepairRequireWardAccess.Value;
			bool noPlacementCost = player.m_noPlacementCost;
			bool noWorkbenchKey = (Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.GetGlobalKey((GlobalKeys)27);
			foreach (WearNTear item in hashSet)
			{
				if (num4 >= num3)
				{
					break;
				}
				if (TryRepairWearNTear(item, position, value3, value, value2, noPlacementCost, noWorkbenchKey))
				{
					num4++;
				}
			}
			if (num4 > 0)
			{
				player.FaceLookDirection();
				if (toolItem.m_shared.m_attack != null)
				{
					((Character)player).m_zanim.SetTrigger(toolItem.m_shared.m_attack.m_attackAnimation);
					((Character)player).UseEitr(toolItem.m_shared.m_attack.m_attackEitr);
				}
				if (HammerAreaRepairShowEffect.Value)
				{
					if ((Object)(object)hoveringPiece != (Object)null && hoveringPiece.m_placeEffect != null)
					{
						hoveringPiece.m_placeEffect.Create(((Component)hoveringPiece).transform.position, ((Component)hoveringPiece).transform.rotation, (Transform)null, 1f, -1, ((Character)player).GetZDOID());
					}
					else if ((Object)(object)repairPiece != (Object)null && repairPiece.m_placeEffect != null)
					{
						repairPiece.m_placeEffect.Create(((Component)player).transform.position, Quaternion.identity, (Transform)null, 1f, -1, ((Character)player).GetZDOID());
					}
				}
				float num5 = player.GetBuildStamina();
				if (HammerAreaRepairStaminaDrainPerPiece.Value)
				{
					num5 *= (float)num4;
				}
				((Character)player).UseStamina(num5);
				if (toolItem.m_shared.m_useDurability)
				{
					float num6 = toolItem.m_shared.m_useDurabilityDrain * Game.m_durabilityRate;
					if (HammerAreaRepairDurabilityDrainPerPiece.Value)
					{
						num6 *= (float)num4;
					}
					toolItem.m_durability = Mathf.Max(0f, toolItem.m_durability - num6);
				}
				if (HammerAreaRepairNotification.Value)
				{
					string hammerRepairNotification = GetHammerRepairNotification(num4);
					((Character)player).Message((MessageType)1, hammerRepairNotification, 0, (Sprite)null, false);
				}
				Log.LogInfo((object)string.Format("[{0}] {1} estrutura(s) reparada(s) em área (Raio: {2}m).", "Pit Reparador", num4, num));
			}
			else if ((Object)(object)hoveringPiece != (Object)null)
			{
				((Character)player).Message((MessageType)1, hoveringPiece.m_name + " $msg_doesnotneedrepair", 0, (Sprite)null, false);
			}
			else
			{
				bool flag = (Localization.instance != null && Localization.instance.GetSelectedLanguage() == "Portuguese_Brazilian") || CultureInfo.CurrentUICulture.TwoLetterISOLanguageName.Equals("pt", StringComparison.OrdinalIgnoreCase);
				((Character)player).Message((MessageType)1, flag ? "Nenhuma estrutura próxima precisa de reparo." : "No nearby structures need repair.", 0, (Sprite)null, false);
			}
		}

		private static string GetHammerRepairNotification(int count)
		{
			if (!string.IsNullOrEmpty(HammerCustomMessage.Value))
			{
				return string.Format(HammerCustomMessage.Value, count);
			}
			if ((Localization.instance != null && Localization.instance.GetSelectedLanguage() == "Portuguese_Brazilian") || CultureInfo.CurrentUICulture.TwoLetterISOLanguageName.Equals("pt", StringComparison.OrdinalIgnoreCase))
			{
				if (count != 1)
				{
					return $"{count} estruturas reparadas na área!";
				}
				return "1 estrutura reparada!";
			}
			if (count != 1)
			{
				return $"{count} pieces repaired in area!";
			}
			return "1 piece repaired!";
		}
	}
	[HarmonyPatch]
	public static class PitReparadorPatches
	{
		[HarmonyPostfix]
		[HarmonyPatch(typeof(CraftingStation), "Interact")]
		public static void CraftingStation_Interact_Postfix(CraftingStation __instance, Humanoid user, bool repeat, bool alt)
		{
			if (PitReparadorPlugin.ModEnabled.Value && PitReparadorPlugin.AutoRepairOnInteract.Value && !repeat && !((Object)(object)user == (Object)null) && !((Object)(object)user != (Object)(object)Player.m_localPlayer) && !((Object)(object)Player.m_localPlayer == (Object)null) && !((Character)Player.m_localPlayer).IsDead() && !((Object)(object)__instance == (Object)null) && __instance.m_canRepair && __instance.InUseDistance(user) && __instance.CheckUsable(Player.m_localPlayer, false))
			{
				PitReparadorPlugin.ExecuteRepairAll(__instance);
			}
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(InventoryGui), "OnRepairPressed")]
		public static bool InventoryGui_OnRepairPressed_Prefix(InventoryGui __instance)
		{
			if (!PitReparadorPlugin.ModEnabled.Value || !PitReparadorPlugin.RepairAllOnClick.Value)
			{
				return true;
			}
			__instance.SetActiveGroup(3, true);
			Player localPlayer = Player.m_localPlayer;
			PitReparadorPlugin.ExecuteRepairAll((localPlayer != null) ? localPlayer.GetCurrentCraftingStation() : null, isManualClick: true);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Player), "Repair")]
		public static bool Player_Repair_Prefix(Player __instance, ItemData toolItem, Piece repairPiece)
		{
			if (!PitReparadorPlugin.ModEnabled.Value || !PitReparadorPlugin.HammerAreaRepairEnabled.Value)
			{
				return true;
			}
			PitReparadorPlugin.ExecuteHammerAreaRepair(__instance, toolItem, repairPiece);
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch(typeof(Character), "Message")]
		public static bool Character_Message_Prefix()
		{
			if (PitReparadorPlugin.SuppressMessages)
			{
				return false;
			}
			return true;
		}
	}
}