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 MastercraftHammer v1.0.1
MastercraftHammer.dll
Decompiled 2 years agousing System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("MastercraftHammer")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Riintouge")] [assembly: AssemblyProduct("MastercraftHammer")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("32bb953c-6574-411a-b1e4-d82bec00fcd0")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.1.0")] namespace MastercraftHammer; [BepInPlugin("com.riintouge.mastercrafthammer", "Mastercraft Hammer", "1.0.1")] [BepInProcess("valheim.exe")] public class MastercraftHammer : BaseUnityPlugin { [HarmonyPatch(typeof(WearNTear))] private class WearNTearPatch { internal static List<uint> WornNTorn = new List<uint>(); private static readonly float[] DamageStateMultipliers = new float[4] { 0f, 0.25f, 0.75f, 1f }; private static bool DoesMaterialPassFilter(MaterialType materialType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Invalid comparison between Unknown and I4 //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 //IL_0040: Unknown result type (might be due to invalid IL or missing references) if (((int)materialType != 3 || !IncludeHardWood.Value) && ((int)materialType != 2 || !IncludeIron.Value) && ((int)materialType != 4 || !IncludeMarble.Value) && ((int)materialType != 1 || !IncludeStone.Value)) { if ((int)materialType == 0) { return IncludeWood.Value; } return false; } return true; } private static float? GetRandomHealth(WearNTear instance, bool forPlacement) { int[] array = new int[4] { (!forPlacement && AllowDestruction.Value) ? DestructionRatio.Value : 0, AllowBroken.Value ? BrokenRatio.Value : 0, AllowWorn.Value ? WornRatio.Value : 0, AllowNew.Value ? NewRatio.Value : 0 }; int num = 0; int[] array2 = array; foreach (int num2 in array2) { num += num2; } if (num == 0) { return null; } int num3 = Random.Range(0, num); int num4 = 0; for (int j = 0; j < array.Length; j++) { num4 += array[j]; if (num3 < num4) { return Mathf.Floor(instance.m_health * DamageStateMultipliers[j]); } } return null; } private static void RandomizeHealth(WearNTear instance, ZNetView netView, bool forPlacement) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) ZDO zDO = netView.GetZDO(); if (!DoesMaterialPassFilter(instance.m_materialType) || (EnableSingleTouch.Value && WornNTorn.Contains(((ZDOID)(ref zDO.m_uid)).ID))) { return; } float num = GetRandomHealth(instance, forPlacement) ?? instance.m_health; if (num == 0f) { instance.Remove(); return; } if (EnableSingleTouch.Value) { WornNTorn.Add(((ZDOID)(ref zDO.m_uid)).ID); } if (num != zDO.GetFloat("health", instance.m_health)) { zDO.Set("health", num); netView.InvokeRPC(ZNetView.Everybody, "WNTHealthChanged", new object[1] { num }); } } [HarmonyPatch("OnPlaced")] [HarmonyPostfix] private static void OnPlacedPostfix(ref WearNTear __instance, ref ZNetView ___m_nview) { if (IsEnabled.Value && RandomizeStateOnPlacement.Value) { RandomizeHealth(__instance, ___m_nview, forPlacement: true); } } [HarmonyPatch("Remove")] [HarmonyPrefix] private static void RemovePrefix(ref WearNTear __instance, ref ZNetView ___m_nview, out uint __state) { __state = ((ZDOID)(ref ___m_nview.GetZDO().m_uid)).ID; } [HarmonyPatch("Remove")] [HarmonyPostfix] private static void RemovePostfix(ref WearNTear __instance, ref ZNetView ___m_nview, ref uint __state) { WornNTorn.Remove(__state); } [HarmonyPatch("Repair")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> RepairPatch(IEnumerable<CodeInstruction> instructionsIn) { List<CodeInstruction> list = new List<CodeInstruction>(instructionsIn); int num = -1; for (int i = 0; i + 3 < list.Count; i++) { if (num != -1 && list[i].opcode == OpCodes.Ldfld && list[i + 1].opcode == OpCodes.Blt_Un && list[i + 2].opcode == OpCodes.Ldc_I4_0 && list[i + 3].opcode == OpCodes.Ret) { if (((FieldInfo)list[i].operand).Name == "m_health") { for (int j = num + 1; j <= i + 3; j++) { list[j].opcode = OpCodes.Nop; } } } else if (list[i].opcode == OpCodes.Ret) { num = i; } } return list; } [HarmonyPatch("Repair")] [HarmonyPrefix] private static bool RepairPrefix(ref WearNTear __instance, ref ZNetView ___m_nview, ref bool __result) { if (!IsEnabled.Value && ___m_nview.IsValid() && ___m_nview.GetZDO().GetFloat("health", __instance.m_health) >= __instance.m_health) { __result = false; return false; } return true; } [HarmonyPatch("RPC_Repair")] [HarmonyPrefix] private static bool RPC_RepairPrefix(ref WearNTear __instance, ref ZNetView ___m_nview, ref long sender) { if (IsEnabled.Value && RandomizeStateOnRepair.Value && sender == ZDOMan.GetSessionID() && ___m_nview.IsValid() && ___m_nview.IsOwner() && Object.op_Implicit((Object)(object)ZNet.instance) && ZNet.instance.IsServer() && ZNet.instance.GetPeerConnections() == 0 && Object.op_Implicit((Object)(object)Player.m_localPlayer)) { RandomizeHealth(__instance, ___m_nview, forPlacement: false); return false; } return true; } } public static ConfigEntry<bool> IsEnabled; public static ConfigEntry<bool> LoadOnStart; public static ConfigEntry<bool> RandomizeStateOnPlacement; public static ConfigEntry<bool> RandomizeStateOnRepair; public static ConfigEntry<bool> IncludeHardWood; public static ConfigEntry<bool> IncludeIron; public static ConfigEntry<bool> IncludeMarble; public static ConfigEntry<bool> IncludeStone; public static ConfigEntry<bool> IncludeWood; public static ConfigEntry<bool> EnableSingleTouch; public static ConfigEntry<bool> ResetSingleTouch; public static ConfigEntry<bool> AllowNew; public static ConfigEntry<int> NewRatio; public static ConfigEntry<bool> AllowWorn; public static ConfigEntry<int> WornRatio; public static ConfigEntry<bool> AllowBroken; public static ConfigEntry<int> BrokenRatio; public static ConfigEntry<bool> AllowDestruction; public static ConfigEntry<int> DestructionRatio; private readonly Harmony Harmony = new Harmony("com.riintouge.mastercrafthammer"); private void Awake() { IsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("0 - Core", "Enable", true, "Whether this plugin has any effect when loaded."); LoadOnStart = ((BaseUnityPlugin)this).Config.Bind<bool>("0 - Core", "LoadOnStart", true, "Whether this plugin loads on game start."); RandomizeStateOnPlacement = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "RandomizeOnPlacement", false, "Affect objects newly placed into the world."); RandomizeStateOnRepair = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "RandomizeOnRepair", false, "Affect objects undergoing repairs. Only works in singleplayer!"); IncludeHardWood = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Filter", "IncludeHardWood", true, "Affect hardwood objects."); IncludeIron = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Filter", "IncludeIron", true, "Affect iron objects."); IncludeMarble = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Filter", "IncludeMarble", true, "Affect marble objects."); IncludeStone = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Filter", "IncludeStone", true, "Affect stone objects."); IncludeWood = ((BaseUnityPlugin)this).Config.Bind<bool>("2 - Filter", "IncludeWood", true, "Affect wooden objects."); EnableSingleTouch = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Single Touch", "EnableSingleTouch", false, "Prevent objects from being affected more than once during a single session. Does not persist."); ResetSingleTouch = ((BaseUnityPlugin)this).Config.Bind<bool>("3 - Single Touch", "ResetSingleTouch", false, "Toggle to true to reset the list of single-touched objects."); AllowNew = ((BaseUnityPlugin)this).Config.Bind<bool>("4 - New", "AllowNew", true, "Whether objects may be fully restored."); NewRatio = ((BaseUnityPlugin)this).Config.Bind<int>("4 - New", "NewRatio", 1, "The Value:X chance, where X is the sum of allowed ratios, the object will be fully restored."); AllowWorn = ((BaseUnityPlugin)this).Config.Bind<bool>("5 - Worn", "AllowWorn", true, "Whether objects may be made to appear worn."); WornRatio = ((BaseUnityPlugin)this).Config.Bind<int>("5 - Worn", "WornRatio", 1, "The Value:X chance, where X is the sum of allowed ratios, the object will be made to appear worn."); AllowBroken = ((BaseUnityPlugin)this).Config.Bind<bool>("6 - Broken", "AllowBroken", true, "Whether objects may be made to appear broken."); BrokenRatio = ((BaseUnityPlugin)this).Config.Bind<int>("6 - Broken", "BrokenRatio", 1, "The Value:X chance, where X is the sum of allowed ratios, the object will be made to appear broken."); AllowDestruction = ((BaseUnityPlugin)this).Config.Bind<bool>("7 - Destruction", "AllowDestruction", false, "Whether objects may be destroyed completely. Use with caution! There is no undo."); DestructionRatio = ((BaseUnityPlugin)this).Config.Bind<int>("7 - Destruction", "DestructionRatio", 0, "The Value:X chance, where X is the sum of allowed ratios, the object will be destroyed."); if (LoadOnStart.Value) { Harmony.PatchAll(); AllowDestruction.Value = false; DestructionRatio.Value = 0; ResetSingleTouch.Value = false; ((BaseUnityPlugin)this).Config.SettingChanged += Config_SettingChanged; } } private void Config_SettingChanged(object sender, SettingChangedEventArgs e) { if (e.ChangedSetting == ResetSingleTouch && ResetSingleTouch.Value) { WearNTearPatch.WornNTorn.Clear(); ((MonoBehaviour)this).StartCoroutine("DelayResetResetSingleTouch"); } } private IEnumerator DelayResetResetSingleTouch() { yield return (object)new WaitForSecondsRealtime(0.1f); ResetSingleTouch.Value = false; } }