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 CrownedButcher v1.0.0
CrownedButcher.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; 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("CrownedButcher")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CrownedButcher")] [assembly: AssemblyTitle("CrownedButcher")] [assembly: AssemblyVersion("1.0.0.0")] namespace CrownedButcher { public static class Butchery { private const string CrownPrefab = "HelmetCrownofValheim"; private const string KnifePrefab = "KnifeButcher"; private static readonly int ArmedKey = StringExtensionMethods.GetStableHashCode("CrownedButcher_Armed"); private static readonly int ExecutedKey = StringExtensionMethods.GetStableHashCode("CrownedButcher_Executed"); public static void UpdateArmed(Player player) { ZNetView component = ((Component)player).GetComponent<ZNetView>(); if (!((Object)(object)component == (Object)null) && component.IsValid() && component.IsOwner()) { List<ItemData> equippedItems = ((Humanoid)player).GetInventory().GetEquippedItems(); bool flag = equippedItems.Exists((ItemData i) => IsPrefab(i, "HelmetCrownofValheim")) && equippedItems.Exists((ItemData i) => IsPrefab(i, "KnifeButcher")); component.GetZDO().Set(ArmedKey, flag); } } public static bool CanHit(Character target, Humanoid attacker) { if (!target.IsTamed()) { return CanExecute((Character)(object)attacker, target); } return true; } public static bool IsExecution(Character target, HitData hit) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)hit.m_hitType != 2 || hit.m_ranged) { return false; } return CanExecute(hit.GetAttacker(), target); } public static void MarkExecuted(Character target) { ((Component)target).GetComponent<ZNetView>().GetZDO().Set(ExecutedKey, true); } public static bool WasExecuted(Component mob) { ZNetView component = mob.GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { return component.GetZDO().GetBool(ExecutedKey, false); } return false; } private static bool CanExecute(Character attacker, Character target) { if (!(attacker is Player) || target.IsPlayer() || target.IsBoss()) { return false; } if ((Object)(object)((Component)target).GetComponent<Piece>() != (Object)null) { return false; } ZNetView component = ((Component)attacker).GetComponent<ZNetView>(); if ((Object)(object)component != (Object)null && component.IsValid()) { return component.GetZDO().GetBool(ArmedKey, false); } return false; } private static bool IsPrefab(ItemData item, string name) { if ((Object)(object)item.m_dropPrefab != (Object)null) { return ((Object)item.m_dropPrefab).name == name; } return false; } } [BepInPlugin("lance.crownedbutcher", "Crowned Butcher", "1.0.0")] public class Plugin : BaseUnityPlugin { private const string Guid = "lance.crownedbutcher"; internal static ManualLogSource Log; internal static ConfigEntry<bool> GuaranteeTrophy; private Harmony harmony; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; GuaranteeTrophy = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "GuaranteeTrophy", true, "Mobs you execute always drop their trophy (if they have one)."); harmony = Harmony.CreateAndPatchAll(typeof(Plugin).Assembly, "lance.crownedbutcher"); } private void OnDestroy() { Harmony obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } } namespace CrownedButcher.Patches { [HarmonyPatch(typeof(Humanoid), "SetupEquipment")] internal static class EquipmentPatch { private static void Postfix(Humanoid __instance) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { Butchery.UpdateArmed(val); } } } [HarmonyPatch(typeof(Character), "RPC_Damage")] internal static class ExecutePatch { private static void Prefix(Character __instance, HitData hit, out bool __state) { ZNetView component = ((Component)__instance).GetComponent<ZNetView>(); __state = (Object)(object)component != (Object)null && component.IsValid() && component.IsOwner() && Butchery.IsExecution(__instance, hit); if (__state) { hit.m_blockable = false; hit.m_dodgeable = false; hit.m_damage.m_damage += __instance.GetHealth(); Butchery.MarkExecuted(__instance); } } private static void Postfix(Character __instance, bool __state) { if (__state && __instance.GetHealth() > 0f) { __instance.SetHealth(0f); } } } [HarmonyPatch] internal static class TamedOnlyPatch { private static IEnumerable<MethodBase> TargetMethods() { return from m in AccessTools.GetDeclaredMethods(typeof(Attack)) where m.Name == "DoMeleeAttack" || m.Name.Contains("checkHits") select m; } private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, MethodBase original) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown FieldInfo tamedOnly = AccessTools.Field(typeof(SharedData), "m_tamedOnly"); MethodInfo isTamed = AccessTools.Method(typeof(Character), "IsTamed", Type.EmptyTypes, (Type[])null); CodeMatcher val = new CodeMatcher(instructions, (ILGenerator)null).MatchForward(true, (CodeMatch[])(object)new CodeMatch[4] { new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.LoadsField(i, tamedOnly, false)), (string)null), new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => i.opcode == OpCodes.Brfalse || i.opcode == OpCodes.Brfalse_S), (string)null), new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.IsLdloc(i, (LocalBuilder)null)), (string)null), new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction i) => CodeInstructionExtensions.Calls(i, isTamed)), (string)null) }); if (val.IsInvalid) { Plugin.Log.LogError((object)("Couldn't find the tamed check in " + original.Name + ", did the game update?")); return val.InstructionEnumeration(); } val.SetInstruction(new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(Butchery), "CanHit", (Type[])null, (Type[])null))); val.Insert((CodeInstruction[])(object)new CodeInstruction[2] { new CodeInstruction(OpCodes.Ldarg_0, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)AccessTools.Field(typeof(Attack), "m_character")) }); return val.InstructionEnumeration(); } } [HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")] internal static class TrophyPatch { private static void Postfix(CharacterDrop __instance, List<KeyValuePair<GameObject, int>> __result) { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Invalid comparison between Unknown and I4 if (!Plugin.GuaranteeTrophy.Value || !Butchery.WasExecuted((Component)(object)__instance)) { return; } foreach (Drop drop in __instance.m_drops) { if (!((Object)(object)drop.m_prefab == (Object)null)) { ItemDrop component = drop.m_prefab.GetComponent<ItemDrop>(); if (!((Object)(object)component == (Object)null) && (int)component.m_itemData.m_shared.m_itemType == 13 && !__result.Exists((KeyValuePair<GameObject, int> d) => (Object)(object)d.Key == (Object)(object)drop.m_prefab)) { __result.Add(new KeyValuePair<GameObject, int>(drop.m_prefab, 1)); } } } } } }