Decompiled source of DvergrCraftsmanship v0.1.0

DvergrCraftsmanship.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
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: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyCompany("DvergrCraftsmanship")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Building piece structural integrity scales with the placer's Crafting skill.")]
[assembly: AssemblyFileVersion("0.1.0.0")]
[assembly: AssemblyInformationalVersion("0.1.0+bee29c368a3b3a04c8242bab80c2c7dd5e5d3f95")]
[assembly: AssemblyProduct("DvergrCraftsmanship")]
[assembly: AssemblyTitle("DvergrCraftsmanship")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.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.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace DvergrCraftsmanship
{
	internal static class CraftsmanshipService
	{
		private static readonly MethodInfo CheckCanRemovePieceMethod = AccessTools.Method(typeof(Player), "CheckCanRemovePiece", (Type[])null, (Type[])null);

		private static readonly MethodInfo GetBuildStaminaMethod = AccessTools.Method(typeof(Player), "GetBuildStamina", (Type[])null, (Type[])null);

		private static readonly MethodInfo ClearCachedSupportMethod = AccessTools.Method(typeof(WearNTear), "ClearCachedSupport", (Type[])null, (Type[])null);

		private static readonly FieldInfo ClearCachedSupportField = AccessTools.Field(typeof(WearNTear), "m_clearCachedSupport");

		private static readonly FieldInfo SkillsPlayerField = AccessTools.Field(typeof(Skills), "m_player");

		private static readonly FieldInfo CharacterZanimField = AccessTools.Field(typeof(Character), "m_zanim");

		private static readonly FieldInfo HudHoverNameField = AccessTools.Field(typeof(Hud), "m_hoverName");

		private static bool s_hasPendingPlacement;

		private static long s_pendingPlayerId;

		private static float s_pendingSkillLevel;

		private static float s_pendingMultiplier;

		internal static void CapturePlacementSkill(Player player)
		{
			s_hasPendingPlacement = false;
			if (IsEnabled() && !((Object)(object)player == (Object)null))
			{
				float craftingSkillLevel = GetCraftingSkillLevel(player);
				s_pendingPlayerId = player.GetPlayerID();
				s_pendingSkillLevel = craftingSkillLevel;
				s_pendingMultiplier = ComputeMultiplier(craftingSkillLevel);
				s_hasPendingPlacement = true;
			}
		}

		internal static void ClearPendingPlacement()
		{
			s_hasPendingPlacement = false;
		}

		internal static void StampPieceFromPendingPlacement(Piece piece, long creator)
		{
			if (!s_hasPendingPlacement || (Object)(object)piece == (Object)null || creator != s_pendingPlayerId)
			{
				return;
			}
			try
			{
				WearNTear component = ((Component)piece).GetComponent<WearNTear>();
				if ((Object)(object)component != (Object)null)
				{
					StampWearNTear(component, s_pendingSkillLevel, s_pendingMultiplier, force: true);
				}
			}
			finally
			{
				ClearPendingPlacement();
			}
		}

		internal static void RegisterReinforceRpc(WearNTear wear)
		{
			if ((Object)(object)wear == (Object)null)
			{
				return;
			}
			ZNetView component = ((Component)wear).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.GetZDO() != null)
			{
				component.Register<float, float>("DvergrCraft_Reinforce", (Action<long, float, float>)delegate(long _, float skillLevel, float multiplier)
				{
					TryApplyReinforcement(wear, skillLevel, multiplier);
				});
			}
		}

		internal static void ApplyCraftsmanshipToSupportLoss(WearNTear wear, float maxSupport, ref float horizontalLoss, ref float verticalLoss)
		{
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_0193: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Unknown result type (might be due to invalid IL or missing references)
			if (!IsEnabled() || (Object)(object)wear == (Object)null || maxSupport <= 0f)
			{
				return;
			}
			ZNetView component = ((Component)wear).GetComponent<ZNetView>();
			bool flag = (Object)(object)component != (Object)null && component.IsValid();
			bool flag2 = flag && component.IsOwner();
			ZDO val = (flag ? component.GetZDO() : null);
			string prefabName = Utils.GetPrefabName(((Object)((Component)wear).gameObject).name);
			if (val == null)
			{
				SupportTraceLog($"Support material patch hit for {prefabName}: no valid ZDO, material={wear.m_materialType}, owner={flag2}, validView={flag}, baseMax={maxSupport:0.###}, frame={Time.frameCount}");
				return;
			}
			float storedMultiplier = GetStoredMultiplier(val, 1f);
			float num = val.GetFloat(ModConstants.ZdoCraftSkillHash, 0f);
			float num2 = val.GetFloat(ZDOVars.s_support, -1f);
			if (storedMultiplier <= 1f)
			{
				SupportTraceLog($"Support material patch hit for {prefabName}: no bonus, material={wear.m_materialType}, owner={flag2}, skill={num:0.#}, multiplier={storedMultiplier:0.###}, max={maxSupport:0.###}, hLoss={horizontalLoss:0.###}, vLoss={verticalLoss:0.###}, currentSupport={num2:0.###}, frame={Time.frameCount}");
			}
			else
			{
				float num3 = horizontalLoss;
				float num4 = verticalLoss;
				horizontalLoss /= storedMultiplier;
				verticalLoss /= storedMultiplier;
				SupportTraceLog($"Support material patch hit for {prefabName}: material={wear.m_materialType}, owner={flag2}, skill={num:0.#}, multiplier={storedMultiplier:0.###}, max={maxSupport:0.###}, hLoss={num3:0.###}->{horizontalLoss:0.###}, vLoss={num4:0.###}->{verticalLoss:0.###}, currentSupport={num2:0.###}, frame={Time.frameCount}");
			}
		}

		internal static bool TryHandleReinforceRepair(Player player, ItemData toolItem)
		{
			if (!IsEnabled() || !ModConfig.EnableReinforce.Value || (Object)(object)player == (Object)null || toolItem == null)
			{
				return false;
			}
			if (!((Character)player).InPlaceMode())
			{
				return false;
			}
			Piece hoveringPiece = player.GetHoveringPiece();
			if ((Object)(object)hoveringPiece == (Object)null)
			{
				return false;
			}
			WearNTear component = ((Component)hoveringPiece).GetComponent<WearNTear>();
			if ((Object)(object)component == (Object)null || !IsFullHealth(component))
			{
				return false;
			}
			float craftingSkillLevel = GetCraftingSkillLevel(player);
			float multiplier = ComputeMultiplier(craftingSkillLevel);
			if (!CanImprove(component, craftingSkillLevel, multiplier))
			{
				return false;
			}
			if (!HasRepairAccess(player, hoveringPiece))
			{
				return true;
			}
			if (!RequestReinforcement(component, craftingSkillLevel, multiplier))
			{
				return false;
			}
			ConsumeRepairSwing(player, hoveringPiece, toolItem, craftingSkillLevel, multiplier);
			return true;
		}

		internal static int GetCraftingSkillLevelForTierNotification(Skills skills)
		{
			if (!IsEnabled() || !ModConfig.EnableTierNotifications.Value || (Object)(object)skills == (Object)null)
			{
				return -1;
			}
			return Mathf.FloorToInt(skills.GetSkillLevel((SkillType)107));
		}

		internal static void ShowTierNotification(Skills skills, int oldLevel)
		{
			if (oldLevel < 0 || !IsEnabled() || !ModConfig.EnableTierNotifications.Value || (Object)(object)skills == (Object)null)
			{
				return;
			}
			int newLevel = Mathf.FloorToInt(skills.GetSkillLevel((SkillType)107));
			int crossedTierThreshold = GetCrossedTierThreshold(oldLevel, newLevel);
			if (crossedTierThreshold > 0)
			{
				object? obj = SkillsPlayerField?.GetValue(skills);
				Player val = (Player)((obj is Player) ? obj : null);
				if (!((Object)(object)val == (Object)null))
				{
					((Character)val).Message((MessageType)1, "Dvergr Craftsmanship: " + GetTierName(crossedTierThreshold) + " reached. Future builds gain stronger integrity.", 0, (Sprite)null);
				}
			}
		}

		internal static void AppendIntegrityHoverText(Hud hud, Player player)
		{
			if (!IsEnabled())
			{
				return;
			}
			ConfigEntry<bool> showIntegrityHoverText = ModConfig.ShowIntegrityHoverText;
			if (showIntegrityHoverText == null || !showIntegrityHoverText.Value || (Object)(object)hud == (Object)null || (Object)(object)player == (Object)null)
			{
				return;
			}
			Piece hoveringPiece = player.GetHoveringPiece();
			if ((Object)(object)hoveringPiece == (Object)null)
			{
				return;
			}
			ZDO zdo = GetZdo(((Component)hoveringPiece).GetComponent<WearNTear>());
			if (zdo == null)
			{
				return;
			}
			float storedMultiplier = GetStoredMultiplier(zdo, 0f);
			if (storedMultiplier <= 0f)
			{
				return;
			}
			float num = zdo.GetFloat(ModConstants.ZdoCraftSkillHash, 0f);
			string text = ((Localization.instance != null) ? Localization.instance.Localize(hoveringPiece.m_name) : hoveringPiece.m_name);
			string arg = FormatBonusPercent(GetSupportLossReductionPercent(storedMultiplier));
			string text2 = $"{arg}% support loss (Crafting {num:0})";
			object obj = HudHoverNameField?.GetValue(hud);
			if (obj != null)
			{
				PropertyInfo property = obj.GetType().GetProperty("text");
				if (!(property == null) && property.CanRead && property.CanWrite)
				{
					string text3 = property.GetValue(obj) as string;
					string value = (string.IsNullOrWhiteSpace(text3) ? (text + "\n" + text2) : (text3 + "\n" + text2));
					property.SetValue(obj, value);
				}
			}
		}

		private static bool IsEnabled()
		{
			return ModConfig.EnableMod?.Value ?? false;
		}

		private static float GetStoredMultiplier(ZDO zdo, float defaultValue)
		{
			if (zdo == null)
			{
				return defaultValue;
			}
			return zdo.GetFloat(ModConstants.ZdoIntegrityMultiplierHash, defaultValue);
		}

		private static float GetSupportLossReductionPercent(float multiplier)
		{
			if (!(multiplier <= 0f))
			{
				return (1f - 1f / multiplier) * 100f;
			}
			return 0f;
		}

		private static float GetCraftingSkillLevel(Player player)
		{
			Skills skills = ((Character)player).GetSkills();
			return Mathf.Clamp((skills != null) ? skills.GetSkillLevel((SkillType)107) : 0f, 0f, 100f);
		}

		private static float ComputeMultiplier(float skillLevel)
		{
			float num = Mathf.Clamp(ModConfig.MaxIntegrityBonusPercent.Value, 20f, 60f);
			return 1f + Mathf.Clamp01(skillLevel / 100f) * (num / 100f);
		}

		private static void StampWearNTear(WearNTear wear, float skillLevel, float multiplier, bool force)
		{
			ZNetView component = ((Component)wear).GetComponent<ZNetView>();
			if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner())
			{
				ZDO zDO = component.GetZDO();
				if (zDO != null && (force || CanImprove(zDO, skillLevel, multiplier)))
				{
					zDO.Set(ModConstants.ZdoCraftSkillHash, skillLevel);
					zDO.Set(ModConstants.ZdoIntegrityMultiplierHash, multiplier);
					MarkSupportDirty(wear);
					DebugLog($"Stamped {((Object)wear).name}: Crafting {skillLevel:0}, integrity x{multiplier:0.###}");
				}
			}
		}

		private static bool RequestReinforcement(WearNTear wear, float skillLevel, float multiplier)
		{
			ZNetView component = ((Component)wear).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return false;
			}
			ZDO zDO = component.GetZDO();
			if (zDO == null || !CanImprove(zDO, skillLevel, multiplier))
			{
				return false;
			}
			if (component.IsOwner())
			{
				return TryApplyReinforcement(wear, skillLevel, multiplier);
			}
			component.InvokeRPC("DvergrCraft_Reinforce", new object[2] { skillLevel, multiplier });
			return true;
		}

		private static bool TryApplyReinforcement(WearNTear wear, float skillLevel, float multiplier)
		{
			ZNetView component = ((Component)wear).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid() || !component.IsOwner())
			{
				return false;
			}
			ZDO zDO = component.GetZDO();
			if (zDO == null || !CanImprove(zDO, skillLevel, multiplier))
			{
				return false;
			}
			zDO.Set(ModConstants.ZdoCraftSkillHash, skillLevel);
			zDO.Set(ModConstants.ZdoIntegrityMultiplierHash, multiplier);
			MarkSupportDirty(wear);
			DebugLog($"Reinforced {((Object)wear).name}: Crafting {skillLevel:0}, integrity x{multiplier:0.###}");
			return true;
		}

		private static bool CanImprove(WearNTear wear, float skillLevel, float multiplier)
		{
			ZDO zdo = GetZdo(wear);
			if (zdo != null)
			{
				return CanImprove(zdo, skillLevel, multiplier);
			}
			return false;
		}

		private static bool CanImprove(ZDO zdo, float skillLevel, float multiplier)
		{
			float num = zdo.GetFloat(ModConstants.ZdoCraftSkillHash, 0f);
			float num2 = zdo.GetFloat(ModConstants.ZdoIntegrityMultiplierHash, 1f);
			int num3 = Mathf.Max(1, ModConfig.MinimumReinforceSkillDelta.Value);
			if (skillLevel >= num + (float)num3)
			{
				return multiplier > num2;
			}
			return false;
		}

		private static bool HasRepairAccess(Player player, Piece piece)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			if (!PrivateArea.CheckAccess(((Component)piece).transform.position, 0f, true, false))
			{
				return false;
			}
			if (CheckCanRemovePieceMethod == null)
			{
				ManualLogSource log = DvergrCraftsmanshipPlugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"Unable to validate build-station repair access; reinforcement skipped.");
				}
				return false;
			}
			object obj = CheckCanRemovePieceMethod.Invoke(player, new object[1] { piece });
			bool flag = default(bool);
			int num;
			if (obj is bool)
			{
				flag = (bool)obj;
				num = 1;
			}
			else
			{
				num = 0;
			}
			return (byte)((uint)num & (flag ? 1u : 0u)) != 0;
		}

		private static bool IsFullHealth(WearNTear wear)
		{
			ZDO zdo = GetZdo(wear);
			if (zdo != null)
			{
				return zdo.GetFloat(ZDOVars.s_health, wear.m_health) >= wear.m_health;
			}
			return false;
		}

		private static ZDO GetZdo(WearNTear wear)
		{
			ZNetView component = ((Component)wear).GetComponent<ZNetView>();
			if ((Object)(object)component == (Object)null || !component.IsValid())
			{
				return null;
			}
			return component.GetZDO();
		}

		private static void MarkSupportDirty(WearNTear wear)
		{
			ClearCachedSupportField?.SetValue(wear, true);
			ClearCachedSupportMethod?.Invoke(wear, Array.Empty<object>());
		}

		private static void ConsumeRepairSwing(Player player, Piece piece, ItemData toolItem, float skillLevel, float multiplier)
		{
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			player.FaceLookDirection();
			TriggerRepairAnimation(player, toolItem);
			piece.m_placeEffect.Create(((Component)piece).transform.position, ((Component)piece).transform.rotation, (Transform)null, 1f, -1);
			string arg = ((Localization.instance != null) ? Localization.instance.Localize(piece.m_name) : piece.m_name);
			float supportLossReductionPercent = GetSupportLossReductionPercent(multiplier);
			((Character)player).Message((MessageType)1, $"Reinforced {arg}: Crafting {skillLevel:0}, support loss -{supportLossReductionPercent:0.#}%", 0, (Sprite)null);
			ConsumeBuildStamina(player);
			((Character)player).UseEitr(toolItem.m_shared.m_attack.m_attackEitr);
			if (toolItem.m_shared.m_useDurability)
			{
				toolItem.m_durability -= toolItem.m_shared.m_useDurabilityDrain;
			}
		}

		private static void TriggerRepairAnimation(Player player, ItemData toolItem)
		{
			object obj = CharacterZanimField?.GetValue(player);
			if (obj != null)
			{
				AccessTools.Method(obj.GetType(), "SetTrigger", new Type[1] { typeof(string) }, (Type[])null)?.Invoke(obj, new object[1] { toolItem.m_shared.m_attack.m_attackAnimation });
			}
		}

		private static void ConsumeBuildStamina(Player player)
		{
			if (GetBuildStaminaMethod?.Invoke(player, Array.Empty<object>()) is float num)
			{
				((Character)player).UseStamina(num);
			}
		}

		private static int GetCrossedTierThreshold(int oldLevel, int newLevel)
		{
			int result = 0;
			int[] array = new int[4] { 25, 50, 75, 100 };
			foreach (int num in array)
			{
				if (oldLevel < num && newLevel >= num)
				{
					result = num;
				}
			}
			return result;
		}

		private static string GetTierName(int threshold)
		{
			return threshold switch
			{
				25 => "Apprentice Craftsman", 
				50 => "Journeyman Craftsman", 
				75 => "Artisan Craftsman", 
				100 => "Master Craftsman", 
				_ => "Craftsman", 
			};
		}

		private static string FormatBonusPercent(float value)
		{
			if (!(Math.Abs(value - Mathf.Round(value)) < 0.05f))
			{
				return value.ToString("+0.#;-0.#;0");
			}
			return value.ToString("+0;-0;0");
		}

		private static void DebugLog(string message)
		{
			ConfigEntry<bool> debugLogging = ModConfig.DebugLogging;
			if (debugLogging != null && debugLogging.Value)
			{
				ManualLogSource log = DvergrCraftsmanshipPlugin.Log;
				if (log != null)
				{
					log.LogInfo((object)message);
				}
			}
		}

		private static void SupportTraceLog(string message)
		{
			DebugLog(message);
		}
	}
	[BepInPlugin("com.cdjensen.dvergrcraftsmanship", "Dvergr Craftsmanship", "0.1.0")]
	public sealed class DvergrCraftsmanshipPlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Log;

		private Harmony harmony;

		private void Awake()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			ModConfig.Bind(((BaseUnityPlugin)this).Config);
			harmony = new Harmony("com.cdjensen.dvergrcraftsmanship");
			harmony.PatchAll(typeof(DvergrCraftsmanshipPlugin).Assembly);
			Log.LogInfo((object)"Dvergr Craftsmanship 0.1.0 loaded.");
		}

		private void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}
	}
	internal static class ModConfig
	{
		internal static ConfigEntry<bool> EnableMod;

		internal static ConfigEntry<float> MaxIntegrityBonusPercent;

		internal static ConfigEntry<bool> EnableReinforce;

		internal static ConfigEntry<int> MinimumReinforceSkillDelta;

		internal static ConfigEntry<bool> EnableTierNotifications;

		internal static ConfigEntry<bool> ShowIntegrityHoverText;

		internal static ConfigEntry<bool> DebugLogging;

		internal static void Bind(ConfigFile config)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			EnableMod = config.Bind<bool>("DvergrCraftsmanship", "EnableMod", true, "Enable Crafting-skill-based structural integrity bonuses.");
			MaxIntegrityBonusPercent = config.Bind<float>("DvergrCraftsmanship", "MaxIntegrityBonusPercent", 40f, new ConfigDescription("Maximum craftsmanship bonus at Crafting skill 100. Default 40 means support loss is divided by 1.4 at skill 100.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(20f, 60f), Array.Empty<object>()));
			EnableReinforce = config.Bind<bool>("DvergrCraftsmanship", "EnableReinforce", true, "Allow hammer repair on full-health pieces to reinforce them when the repairer's Crafting skill is high enough.");
			MinimumReinforceSkillDelta = config.Bind<int>("DvergrCraftsmanship", "MinimumReinforceSkillDelta", 5, new ConfigDescription("Minimum Crafting skill improvement required to reinforce an already-crafted piece.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 100), Array.Empty<object>()));
			EnableTierNotifications = config.Bind<bool>("DvergrCraftsmanship", "EnableTierNotifications", true, "Show a short message when Crafting reaches Dvergr Craftsmanship thresholds: 25, 50, 75, and 100.");
			ShowIntegrityHoverText = config.Bind<bool>("DvergrCraftsmanship", "ShowIntegrityHoverText", true, "Show a concise Crafting skill and support-loss reduction line while hammer-hovering crafted pieces.");
			DebugLogging = config.Bind<bool>("DvergrCraftsmanship", "DebugLogging", false, "Enable verbose debug logging for placement stamps and reinforcement.");
		}
	}
	internal static class ModConstants
	{
		internal const string ModName = "Dvergr Craftsmanship";

		internal const string ModVersion = "0.1.0";

		internal const string ModGuid = "com.cdjensen.dvergrcraftsmanship";

		internal const string ConfigFolder = "DvergrCraftsmanship";

		internal const string ZdoIntegrityMultiplier = "DvergrCraft_IntegrityMult";

		internal const string ZdoCraftSkill = "DvergrCraft_CraftSkill";

		internal const string RpcReinforce = "DvergrCraft_Reinforce";

		internal static readonly int ZdoIntegrityMultiplierHash = StringExtensionMethods.GetStableHashCode("DvergrCraft_IntegrityMult");

		internal static readonly int ZdoCraftSkillHash = StringExtensionMethods.GetStableHashCode("DvergrCraft_CraftSkill");
	}
}
namespace DvergrCraftsmanship.Patches
{
	[HarmonyPatch(typeof(Player), "PlacePiece")]
	internal static class PlayerPlacePiecePatch
	{
		private static void Prefix(Player __instance)
		{
			CraftsmanshipService.CapturePlacementSkill(__instance);
		}

		private static void Finalizer()
		{
			CraftsmanshipService.ClearPendingPlacement();
		}
	}
	[HarmonyPatch(typeof(Piece), "SetCreator")]
	internal static class PieceSetCreatorPatch
	{
		private static void Postfix(Piece __instance, long uid)
		{
			CraftsmanshipService.StampPieceFromPendingPlacement(__instance, uid);
		}
	}
	[HarmonyPatch(typeof(WearNTear), "Awake")]
	internal static class WearNTearAwakePatch
	{
		private static void Postfix(WearNTear __instance)
		{
			CraftsmanshipService.RegisterReinforceRpc(__instance);
		}
	}
	[HarmonyPatch(typeof(WearNTear), "GetMaterialProperties")]
	internal static class WearNTearGetMaterialPropertiesPatch
	{
		private static void Postfix(WearNTear __instance, float maxSupport, ref float horizontalLoss, ref float verticalLoss)
		{
			CraftsmanshipService.ApplyCraftsmanshipToSupportLoss(__instance, maxSupport, ref horizontalLoss, ref verticalLoss);
		}
	}
	[HarmonyPatch(typeof(Player), "Repair")]
	internal static class PlayerRepairPatch
	{
		private static bool Prefix(Player __instance, ItemData toolItem)
		{
			return !CraftsmanshipService.TryHandleReinforceRepair(__instance, toolItem);
		}
	}
	[HarmonyPatch(typeof(Hud), "UpdateCrosshair")]
	internal static class HudUpdateCrosshairPatch
	{
		private static void Postfix(Hud __instance, Player player)
		{
			CraftsmanshipService.AppendIntegrityHoverText(__instance, player);
		}
	}
	[HarmonyPatch(typeof(Skills), "RaiseSkill")]
	internal static class SkillsRaiseSkillPatch
	{
		private static void Prefix(Skills __instance, SkillType skillType, ref int __state)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			__state = (((int)skillType == 107) ? CraftsmanshipService.GetCraftingSkillLevelForTierNotification(__instance) : (-1));
		}

		private static void Postfix(Skills __instance, SkillType skillType, int __state)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0003: Invalid comparison between Unknown and I4
			if ((int)skillType == 107)
			{
				CraftsmanshipService.ShowTierNotification(__instance, __state);
			}
		}
	}
}