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 HammerRepairRadius v1.0.1
HammerRepairRadius.dll
Decompiled 11 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ConditionalConfigSync; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("HammerRepairRadius")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1")] [assembly: AssemblyProduct("HammerRepairRadius")] [assembly: AssemblyTitle("HammerRepairRadius")] [assembly: AssemblyVersion("1.0.1.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 HammerRepairRadius { public enum RepairCenter { HoveredPieceOrPlayer, HoveredPiece, Player } public enum CostMode { PerSwing, PerPiece } [BepInPlugin("com.dreich.hammerrepairradius", "Hammer Repair Radius", "1.0.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class HammerRepairRadiusPlugin : BaseUnityPlugin { public const string PluginGuid = "com.dreich.hammerrepairradius"; public const string PluginName = "Hammer Repair Radius"; public const string PluginVersion = "1.0.1"; internal const string HammerPrefab = "Hammer"; internal const string ConfigSyncGuid = "_shudnal.ConditionalConfigSync"; internal static bool ConfigSyncInstalled; private static ConfigEntry<bool> lockConfigurationSetting; internal static ManualLogSource Log; internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<float> BaseRadius; internal static ConfigEntry<float> RadiusPerLevel; internal static ConfigEntry<float> MaxRadius; internal static ConfigEntry<RepairCenter> Center; internal static ConfigEntry<bool> RequireCraftingStation; internal static ConfigEntry<bool> RespectWards; internal static ConfigEntry<bool> OnlyPlayerBuiltPieces; internal static ConfigEntry<bool> RespectRepairEnemyStructures; internal static ConfigEntry<CostMode> Costs; internal static ConfigEntry<bool> EnableHammerUpgrades; internal static ConfigEntry<int> HammerMaxLevel; internal static ConfigEntry<string> UpgradeRequirements; internal static ConfigEntry<int> MaxEffectsPerSwing; internal static ConfigEntry<bool> ShowRadiusInTooltip; internal static ConfigEntry<bool> LogRepairs; private static Harmony harmony; private void Awake() { //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Expected O, but got Unknown //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; ConfigSyncInstalled = Chainloader.PluginInfos.ContainsKey("_shudnal.ConditionalConfigSync"); if (ConfigSyncInstalled) { lockConfigurationSetting = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Lock Configuration", true, "If on, the configuration is locked and can be changed by server admins only."); InitConfigSync(lockConfigurationSetting); } else { Log.LogInfo((object)"ConditionalConfigSync not found; using local config only (no server sync)."); } Enabled = BindServerControlled("General", "Enabled", defaultValue: true, "Turn area repair on or off. When off, the hammer repairs one piece like vanilla."); BaseRadius = BindServerControlled("Radius", "BaseRadius", 5f, "Base repair radius in meters. Radius = BaseRadius + RadiusPerLevel x tool level. With the defaults, a level 1 hammer repairs within 6 m and a level 4 hammer within 9 m. Set BaseRadius to 4 if you want a level 1 hammer to be exactly 5 m."); RadiusPerLevel = BindServerControlled("Radius", "RadiusPerLevel", 1f, "Extra meters of radius for every level (quality) of the hammer."); MaxRadius = BindServerControlled("Radius", "MaxRadius", 0f, "Upper limit on the radius in meters. 0 = no limit."); Center = BindServerControlled("Radius", "RepairCenter", RepairCenter.HoveredPieceOrPlayer, "Where the repair circle is centred. HoveredPieceOrPlayer = the piece you aim at, or yourself if you aim at nothing. HoveredPiece = only works when aiming at a piece (like vanilla). Player = always centred on you."); RequireCraftingStation = BindServerControlled("Rules", "RequireCraftingStation", defaultValue: true, "Vanilla rule: a piece only gets repaired if the crafting station it was built with is in range of you."); RespectWards = BindServerControlled("Rules", "RespectWards", defaultValue: true, "Skip pieces inside wards you do not have access to."); OnlyPlayerBuiltPieces = BindServerControlled("Rules", "OnlyPlayerBuiltPieces", defaultValue: false, "Only repair pieces that a player built (skips dungeon and enemy structures)."); RespectRepairEnemyStructures = BindServerControlled("Rules", "RespectRepairEnemyStructuresStations", defaultValue: true, "If the Repair Enemy Structures mod is installed, honour its per-structure station requirements during area repair."); Costs = BindServerControlled("Costs", "CostMode", CostMode.PerSwing, "PerSwing = stamina and durability are paid once per swing, like a single vanilla repair. PerPiece = paid for every piece repaired (stops when you run out)."); EnableHammerUpgrades = BindServerControlled("Upgrades", "EnableHammerUpgrades", defaultValue: true, "Vanilla hammers cannot be upgraded, so they stay at level 1. Turn this on to allow upgrading the hammer at the workbench so the radius can grow."); HammerMaxLevel = BindServerControlled("Upgrades", "HammerMaxLevel", 4, new ConfigDescription("Highest level the hammer can be upgraded to. Each level needs a higher workbench level.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 10), Array.Empty<object>())); UpgradeRequirements = BindServerControlled("Upgrades", "UpgradeRequirements", "Wood:3,Flint:2", "Materials needed per upgrade level, as ItemPrefab:amount pairs separated by commas. The amount is multiplied by (level - 1), so going to level 3 costs twice as much as level 2."); MaxEffectsPerSwing = BindClientControlled("Effects", "MaxEffectsPerSwing", 10, "Most repair sound/particle effects played per swing, so big repairs do not get loud. 0 = none."); ShowRadiusInTooltip = BindClientControlled("Effects", "ShowRadiusInTooltip", defaultValue: true, "Show the repair radius in the hammer tooltip (also shows the next level's radius in the upgrade screen)."); LogRepairs = BindClientControlled("Debug", "LogRepairs", defaultValue: false, "Log a line every time an area repair runs."); EnableHammerUpgrades.SettingChanged += delegate { HammerUpgrades.Apply(); }; HammerMaxLevel.SettingChanged += delegate { HammerUpgrades.Apply(); }; UpgradeRequirements.SettingChanged += delegate { HammerUpgrades.Apply(); }; harmony = new Harmony("com.dreich.hammerrepairradius"); harmony.PatchAll(); } private ConfigEntry<T> BindServerControlled<T>(string section, string key, T defaultValue, string description) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown return BindServerControlled(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>())); } private ConfigEntry<T> BindServerControlled<T>(string section, string key, T defaultValue, ConfigDescription description) { ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, defaultValue, description); if (ConfigSyncInstalled) { RegisterSynced<T>(val, serverControlled: true); } return val; } private ConfigEntry<T> BindClientControlled<T>(string section, string key, T defaultValue, string description) { ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, defaultValue, description); if (ConfigSyncInstalled) { RegisterSynced<T>(val, serverControlled: false); } return val; } [MethodImpl(MethodImplOptions.NoInlining)] private static void InitConfigSync(ConfigEntry<bool> lockEntry) { ConfigSyncBridge.Init(lockEntry); } [MethodImpl(MethodImplOptions.NoInlining)] private static void RegisterSynced<T>(ConfigEntry<T> entry, bool serverControlled) { ConfigSyncBridge.Add<T>(entry, serverControlled); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } harmony = null; } internal static bool IsHammer(ItemData item) { if (item == null) { return false; } if ((Object)(object)item.m_dropPrefab != (Object)null) { return ((Object)item.m_dropPrefab).name == "Hammer"; } GameObject val = (((Object)(object)ObjectDB.instance != (Object)null) ? ObjectDB.instance.GetItemPrefab("Hammer") : null); ItemDrop val2 = (((Object)(object)val != (Object)null) ? val.GetComponent<ItemDrop>() : null); if ((Object)(object)val2 != (Object)null) { return val2.m_itemData.m_shared == item.m_shared; } return false; } internal static float GetRadius(int quality) { float num = BaseRadius.Value + RadiusPerLevel.Value * (float)Mathf.Max(1, quality); if (MaxRadius.Value > 0f) { num = Mathf.Min(num, MaxRadius.Value); } return Mathf.Max(0f, num); } } internal static class ConfigSyncBridge { private static ConfigSync configSync; [MethodImpl(MethodImplOptions.NoInlining)] internal static void Init(ConfigEntry<bool> lockEntry) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown configSync = new ConfigSync("com.dreich.hammerrepairradius") { DisplayName = "Hammer Repair Radius", CurrentVersion = "1.0.1", MinimumRequiredVersion = "1.0.1", ModRequired = false, ModRequirementMode = (ModRequirementMode)1 }; ((ConditionalConfigSync)configSync).AddLockingConfigEntry<bool>(lockEntry); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void Add<T>(ConfigEntry<T> entry, bool serverControlled) { ((ConditionalConfigSync)configSync).AddConfigEntry<T>(entry, (ConfigSyncMode)((!serverControlled) ? 2 : 0)); } } internal static class AreaRepair { private static readonly FieldRef<Character, ZSyncAnimation> ZanimRef = AccessTools.FieldRefAccess<Character, ZSyncAnimation>("m_zanim"); private static readonly FieldRef<Player, bool> NoPlacementCostRef = AccessTools.FieldRefAccess<Player, bool>("m_noPlacementCost"); private static readonly Func<Player, float> GetBuildStamina = AccessTools.MethodDelegate<Func<Player, float>>(AccessTools.Method(typeof(Player), "GetBuildStamina", (Type[])null, (Type[])null), (object)null, true); private static bool enemyStructuresLookedUp; private static Type enemyStationType; private static FieldInfo enemyStationNameField; private static readonly List<Piece> piecesBuffer = new List<Piece>(); internal static void Run(Player player, ItemData tool) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0308: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_01de: 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_01f7: Unknown result type (might be due to invalid IL or missing references) Piece hoveringPiece = player.GetHoveringPiece(); Vector3 center; switch (HammerRepairRadiusPlugin.Center.Value) { case RepairCenter.HoveredPiece: if ((Object)(object)hoveringPiece == (Object)null) { return; } center = ((Component)hoveringPiece).transform.position; break; case RepairCenter.Player: center = ((Component)player).transform.position; break; default: center = (((Object)(object)hoveringPiece != (Object)null) ? ((Component)hoveringPiece).transform.position : ((Component)player).transform.position); break; } float radius = HammerRepairRadiusPlugin.GetRadius(tool.m_quality); piecesBuffer.Clear(); Piece.GetAllPiecesInRadius(center, radius, piecesBuffer); piecesBuffer.Sort(delegate(Piece a, Piece b) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) Vector3 val3 = ((Component)a).transform.position - center; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; val3 = ((Component)b).transform.position - center; return sqrMagnitude.CompareTo(((Vector3)(ref val3)).sqrMagnitude); }); bool flag = HammerRepairRadiusPlugin.Costs.Value == CostMode.PerPiece; float stamina = GetBuildStamina(player); int value = HammerRepairRadiusPlugin.MaxEffectsPerSwing.Value; int num = 0; int num2 = 0; int num3 = 0; string text = null; Piece val = null; foreach (Piece item in piecesBuffer) { if ((Object)(object)item == (Object)null) { continue; } WearNTear component = ((Component)item).GetComponent<WearNTear>(); if ((Object)(object)component == (Object)null || component.GetHealthPercentage() >= 1f || (HammerRepairRadiusPlugin.OnlyPlayerBuiltPieces.Value && !item.IsPlacedByPlayer())) { continue; } string missingStation = GetMissingStation(player, item); if (missingStation != null) { num2++; if (text == null) { text = missingStation; } continue; } if (HammerRepairRadiusPlugin.RespectWards.Value && !PrivateArea.CheckAccess(((Component)item).transform.position, 0f, false, false)) { num3++; continue; } if (flag && !CanAfford(player, tool, stamina)) { break; } if (component.Repair()) { num++; val = item; if (num <= value) { item.m_placeEffect.Create(((Component)item).transform.position, ((Component)item).transform.rotation, (Transform)null, 1f, -1, ((Character)player).GetZDOID()); } if (flag) { PayCosts(player, tool, stamina); } } } piecesBuffer.Clear(); if (num > 0) { player.FaceLookDirection(); ZSyncAnimation val2 = ZanimRef.Invoke((Character)(object)player); if ((Object)(object)val2 != (Object)null) { val2.SetTrigger(tool.m_shared.m_attack.m_attackAnimation); } if (!flag) { PayCosts(player, tool, stamina); } string text2 = ((num == 1) ? Localization.instance.Localize("$msg_repaired", new string[1] { val.m_name }) : $"Repaired {num} pieces"); ((Character)player).Message((MessageType)1, text2, 0, (Sprite)null, false); } else if (num2 > 0) { string text3 = ((text != null) ? Localization.instance.Localize(text) : "crafting station"); ((Character)player).Message((MessageType)2, "Requires a nearby " + text3 + " to repair", 0, (Sprite)null, false); } else if (num3 > 0) { PrivateArea.CheckAccess(center, radius, true, false); ((Character)player).Message((MessageType)2, "$msg_privatezone", 0, (Sprite)null, false); } else if ((Object)(object)hoveringPiece != (Object)null) { ((Character)player).Message((MessageType)1, hoveringPiece.m_name + " $msg_doesnotneedrepair", 0, (Sprite)null, false); } else { ((Character)player).Message((MessageType)1, "Nothing nearby needs repair", 0, (Sprite)null, false); } if (HammerRepairRadiusPlugin.LogRepairs.Value) { HammerRepairRadiusPlugin.Log.LogInfo((object)($"Area repair r={radius:0.#}m (tool level {tool.m_quality}): repaired {num}, " + $"blocked by station {num2}, blocked by ward {num3}")); } } private static string GetMissingStation(Player player, Piece piece) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) Vector3 position = ((Component)player).transform.position; if (HammerRepairRadiusPlugin.RequireCraftingStation.Value && !NoPlacementCostRef.Invoke(player) && (Object)(object)piece.m_craftingStation != (Object)null && !Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(piece.m_craftingStation.m_name, position)) && !ZoneSystem.instance.GetGlobalKey((GlobalKeys)27)) { return piece.m_craftingStation.m_name; } if (HammerRepairRadiusPlugin.RespectRepairEnemyStructures.Value) { if (!enemyStructuresLookedUp) { enemyStructuresLookedUp = true; enemyStationType = AccessTools.TypeByName("RepairEnemyStructures.RepairRequiresStation"); if (enemyStationType != null) { enemyStationNameField = AccessTools.Field(enemyStationType, "StationName"); } } if (enemyStationType != null && enemyStationNameField != null) { Component component = ((Component)piece).GetComponent(enemyStationType); if ((Object)(object)component != (Object)null) { string text = enemyStationNameField.GetValue(component) as string; if (!string.IsNullOrEmpty(text) && !Object.op_Implicit((Object)(object)CraftingStation.HaveBuildStationInRange(text, position))) { return text; } } } } return null; } private static bool CanAfford(Player player, ItemData tool, float stamina) { if (!((Character)player).HaveStamina(stamina)) { return false; } float attackEitr = tool.m_shared.m_attack.m_attackEitr; if (attackEitr > 0f && !((Character)player).HaveEitr(attackEitr)) { return false; } if (tool.m_shared.m_useDurability && tool.m_durability <= 0f) { return false; } return true; } private static void PayCosts(Player player, ItemData tool, float stamina) { ((Character)player).UseStamina(stamina); ((Character)player).UseEitr(tool.m_shared.m_attack.m_attackEitr); if (tool.m_shared.m_useDurability) { tool.m_durability = Mathf.Max(0f, tool.m_durability - tool.m_shared.m_useDurabilityDrain * Game.m_durabilityRate); } } } internal static class HammerUpgrades { private const string HammerPrefab = "Hammer"; private static Recipe cachedRecipe; private static Requirement[] originalResources; private static int originalMaxQuality = -1; private static SharedData cachedShared; internal static void Apply() { //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0277: Expected O, but got Unknown ObjectDB instance = ObjectDB.instance; if ((Object)(object)instance == (Object)null) { return; } GameObject itemPrefab = instance.GetItemPrefab("Hammer"); ItemDrop val = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); Recipe val2 = ((IEnumerable<Recipe>)instance.m_recipes).FirstOrDefault((Func<Recipe, bool>)((Recipe r) => (Object)(object)r != (Object)null && (Object)(object)r.m_item != (Object)null && ((Object)r.m_item).name == "Hammer")); if ((Object)(object)val == (Object)null || (Object)(object)val2 == (Object)null) { HammerRepairRadiusPlugin.Log.LogWarning((object)"Could not find the Hammer item or recipe; upgrades not applied."); return; } SharedData shared = val.m_itemData.m_shared; if (cachedShared != shared) { cachedShared = shared; originalMaxQuality = shared.m_maxQuality; } if ((Object)(object)cachedRecipe != (Object)(object)val2) { cachedRecipe = val2; originalResources = val2.m_resources; } if (!HammerRepairRadiusPlugin.EnableHammerUpgrades.Value) { shared.m_maxQuality = originalMaxQuality; val2.m_resources = originalResources; return; } shared.m_maxQuality = Mathf.Max(1, HammerRepairRadiusPlugin.HammerMaxLevel.Value); Dictionary<string, int> dictionary = ParseRequirements(HammerRepairRadiusPlugin.UpgradeRequirements.Value); List<Requirement> list = new List<Requirement>(); Requirement[] array = originalResources; foreach (Requirement val3 in array) { if (val3 != null) { Requirement val4 = new Requirement { m_resItem = val3.m_resItem, m_amount = val3.m_amount, m_extraAmountOnlyOneIngredient = val3.m_extraAmountOnlyOneIngredient, m_upgraderResource = val3.m_upgraderResource, m_recover = val3.m_recover, m_amountPerLevel = 0 }; string text = (((Object)(object)val3.m_resItem != (Object)null) ? ((Object)val3.m_resItem).name : null); if (text != null && dictionary.TryGetValue(text, out var value)) { val4.m_amountPerLevel = value; dictionary.Remove(text); } list.Add(val4); } } foreach (KeyValuePair<string, int> item in dictionary) { GameObject itemPrefab2 = instance.GetItemPrefab(item.Key); ItemDrop val5 = (((Object)(object)itemPrefab2 != (Object)null) ? itemPrefab2.GetComponent<ItemDrop>() : null); if ((Object)(object)val5 == (Object)null) { HammerRepairRadiusPlugin.Log.LogWarning((object)("UpgradeRequirements: item prefab '" + item.Key + "' not found.")); continue; } list.Add(new Requirement { m_resItem = val5, m_amount = 0, m_amountPerLevel = item.Value, m_recover = true }); } val2.m_resources = list.ToArray(); } private static Dictionary<string, int> ParseRequirements(string value) { Dictionary<string, int> dictionary = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase); string[] array = value.Split(new char[1] { ',' }); for (int i = 0; i < array.Length; i++) { string[] array2 = array[i].Split(new char[1] { ':' }); if (array2.Length == 2) { string text = array2[0].Trim(); if (text.Length != 0 && int.TryParse(array2[1].Trim(), out var result) && result > 0) { dictionary[text] = result; } } } return dictionary; } } [HarmonyPatch(typeof(Player), "Repair")] internal static class PlayerRepairPatch { private static bool Prefix(Player __instance, ItemData toolItem) { if (!HammerRepairRadiusPlugin.Enabled.Value) { return true; } if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || !((Character)__instance).InPlaceMode()) { return true; } if (!HammerRepairRadiusPlugin.IsHammer(toolItem)) { return true; } AreaRepair.Run(__instance, toolItem); return false; } } [HarmonyPatch] internal static class ObjectDBPatches { [HarmonyPostfix] [HarmonyPatch(typeof(ObjectDB), "Awake")] private static void AwakePostfix() { HammerUpgrades.Apply(); } [HarmonyPostfix] [HarmonyPatch(typeof(ObjectDB), "CopyOtherDB")] private static void CopyOtherDBPostfix() { HammerUpgrades.Apply(); } } [HarmonyPatch] internal static class TooltipPatch { private static MethodBase TargetMethod() { return AccessTools.GetDeclaredMethods(typeof(ItemData)).First((MethodInfo m) => m.Name == "GetTooltip" && m.IsStatic && m.GetParameters().Length >= 2 && m.GetParameters()[0].ParameterType == typeof(ItemData) && m.GetParameters()[1].ParameterType == typeof(int)); } private static void Postfix(ItemData item, int qualityLevel, ref string __result) { if (HammerRepairRadiusPlugin.ShowRadiusInTooltip.Value && HammerRepairRadiusPlugin.Enabled.Value && HammerRepairRadiusPlugin.IsHammer(item)) { StringBuilder stringBuilder = new StringBuilder(__result); stringBuilder.Append($"\nRepair radius: <color=orange>{HammerRepairRadiusPlugin.GetRadius(qualityLevel):0.#} m</color>"); __result = stringBuilder.ToString(); } } } }