Please disclose if your mod was created primarily 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 NoUnarmedCombat v1.0.3
NoUnarmedCombat.dll
Decompiled a year agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("NoUnarmedCombat")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("Riintouge")] [assembly: AssemblyProduct("NoUnarmedCombat")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("6245a6e2-549d-4d09-b596-43a8169cad43")] [assembly: AssemblyFileVersion("1.0.3.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.3.0")] namespace NoUnarmedCombat; [BepInPlugin("com.riintouge.nounarmedcombat", "No Unarmed Combat", "1.0.3")] [BepInProcess("valheim.exe")] public class NoUnarmedCombat : BaseUnityPlugin { [HarmonyPatch(typeof(Humanoid))] private class HumanoidPatch { private static bool InStartAttack; private static bool PerformingSecondaryAttack; private static bool SheathedBecauseSwimming; private static bool SkipNextEquipAttempt; private static ItemData[] GetToolbarWeaponsAndShield(Humanoid humanoid) { List<ItemData> list = new List<ItemData>(); humanoid.GetInventory().GetBoundItems(list); List<ItemData> source = (from x in list orderby x.m_gridPos.x where x.GetDurabilityPercentage() > 0f select x).ToList(); return (ItemData[])(object)new ItemData[3] { ((IEnumerable<ItemData>)source).FirstOrDefault((Func<ItemData, bool>)((ItemData itemData) => itemData.IsWeapon() && itemData.IsTwoHanded())), ((IEnumerable<ItemData>)source).FirstOrDefault((Func<ItemData, bool>)((ItemData itemData) => itemData.IsWeapon() && !itemData.IsTwoHanded())), ((IEnumerable<ItemData>)source).FirstOrDefault((Func<ItemData, bool>)((ItemData itemData) => ItemIsShield(itemData))) }; } private static bool HumanoidIsLocalPlayer(Humanoid humanoid) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) if (((Character)humanoid).IsPlayer()) { ZDOID zDOID = ((Character)humanoid).GetZDOID(); return ((ZDOID)(ref zDOID)).UserID == ZDOMan.GetSessionID(); } return false; } private static bool ItemIsShield(ItemData itemData) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 if (itemData == null) { return false; } return (int)itemData.m_shared.m_itemType == 5; } private static void ShowHandItems(ref Humanoid __instance, bool onlyRightHand = false, bool animation = true) { Traverse.Create((object)__instance).Method("ShowHandItems", new Type[2] { typeof(bool), typeof(bool) }, (object[])null).GetValue(new object[2] { onlyRightHand, animation }); } [HarmonyPatch("GetCurrentWeapon")] [HarmonyPostfix] private static ItemData GetCurrentWeaponPostfix(ItemData result, ref Humanoid __instance, ref ItemData ___m_hiddenLeftItem, ref ItemData ___m_hiddenRightItem) { if (InStartAttack && IsEnabled.Value && result == __instance.m_unarmedWeapon?.m_itemData && HumanoidIsLocalPlayer(__instance) && (!PerformingSecondaryAttack || !AllowKick.Value)) { if (UnsheatheOnPunch.Value && (___m_hiddenLeftItem != null || ___m_hiddenRightItem != null)) { return null; } if (ToolbarEquipOnPunch.Value) { ItemData[] toolbarWeaponsAndShield = GetToolbarWeaponsAndShield(__instance); if (toolbarWeaponsAndShield[0] != null || toolbarWeaponsAndShield[1] != null) { return null; } } if (!FallbackFisticuffs.Value) { SkipNextEquipAttempt = true; return null; } } return result; } [HarmonyPatch("StartAttack")] [HarmonyPrefix] private static bool StartAttackPrefix(ref Humanoid __instance, ref bool secondaryAttack) { if (!IsEnabled.Value) { return true; } if (HumanoidIsLocalPlayer(__instance) && Minimap.IsOpen()) { return false; } InStartAttack = true; PerformingSecondaryAttack = secondaryAttack; return true; } [HarmonyPatch("StartAttack")] [HarmonyPostfix] private static void StartAttackPostfix(ref Humanoid __instance, ref ItemData ___m_hiddenLeftItem, ref ItemData ___m_hiddenRightItem, ref ZSyncAnimation ___m_zanim) { bool num = !IsEnabled.Value || !HumanoidIsLocalPlayer(__instance) || __instance.GetCurrentWeapon() != null || !InStartAttack || SkipNextEquipAttempt; InStartAttack = false; PerformingSecondaryAttack = false; SkipNextEquipAttempt = false; if (num) { return; } ItemData val = __instance.RightItem; ItemData val2 = __instance.LeftItem; if (val != null || val2 != null) { return; } ItemData val3 = null; ItemData val4 = null; if (UnsheatheOnPunch.Value && (___m_hiddenRightItem != null || ___m_hiddenLeftItem != null)) { if (!ToolbarEquipOnPunch.Value || (___m_hiddenLeftItem != null && ___m_hiddenRightItem != null)) { ShowHandItems(ref __instance); return; } val = ___m_hiddenRightItem; val2 = ___m_hiddenLeftItem; val3 = ___m_hiddenRightItem; val4 = ___m_hiddenLeftItem; } if (!ToolbarEquipOnPunch.Value || (val3 != null && val4 != null)) { return; } ItemData[] toolbarWeaponsAndShield = GetToolbarWeaponsAndShield(__instance); ItemData val5 = toolbarWeaponsAndShield[0]; ItemData val6 = toolbarWeaponsAndShield[1]; ItemData val7 = toolbarWeaponsAndShield[2]; if (val3 == null && val4 == null) { if (val6 != null && val5 != null) { if (val6.m_gridPos.x < val5.m_gridPos.x) { val3 = val6; val4 = val7; } else { val3 = val5; } } else if (val5 != null) { val3 = val5; } else { val3 = val6; val4 = val7; } } else if (val3 != null && val4 == null) { if (!val3.IsTwoHanded()) { val4 = val7; } } else if (val3 == null && val4 != null && !val4.IsTwoHanded() && !val4.IsWeapon() && ItemIsShield(val4) && val6 != null) { val3 = val6; } if (val != null) { __instance.EquipItem(val, true); } else if (val3 != null && !__instance.IsItemEquiped(val3)) { __instance.EquipItem(val3, true); val = val3; } if (val2 != null) { __instance.EquipItem(val2, true); } else if (val4 != null && !__instance.IsItemEquiped(val4)) { __instance.EquipItem(val4, true); if (val != null && !__instance.IsItemEquiped(val)) { __instance.EquipItem(val, true); } else { val2 = val4; } } if (val != null || val2 != null) { ___m_zanim.SetTrigger("equip_hip"); } PlayerPatch.RestoreQueuedAttackTimers = true; } [HarmonyPatch("UpdateEquipment")] [HarmonyPrefix] private static void UpdateEquipmentPrefix(ref Humanoid __instance, ref ItemData ___m_leftItem, ref ItemData ___m_rightItem) { if (!HumanoidIsLocalPlayer(__instance)) { return; } if (((Character)__instance).IsSwimming() && !((Character)__instance).IsOnGround()) { SheathedBecauseSwimming |= ___m_leftItem != null || ___m_rightItem != null; } else if (SheathedBecauseSwimming) { if (IsEnabled.Value && UnsheatheAfterSwimming.Value) { ShowHandItems(ref __instance); } SheathedBecauseSwimming = false; } } } [HarmonyPatch(typeof(Player))] private class PlayerPatch { internal static bool RestoreQueuedAttackTimers; private static float LastAttackTimer; private static float LastSecondaryAttackTimer; [HarmonyPatch("PlayerAttackInput")] [HarmonyPrefix] private static void PlayerAttackInputPrefix(ref float ___m_queuedAttackTimer, ref float ___m_queuedSecondAttackTimer) { LastAttackTimer = ___m_queuedAttackTimer; LastSecondaryAttackTimer = ___m_queuedSecondAttackTimer; } [HarmonyPatch("PlayerAttackInput")] [HarmonyPostfix] private static void PlayerAttackInputPostfix(ref float ___m_queuedAttackTimer, ref float ___m_queuedSecondAttackTimer) { if (RestoreQueuedAttackTimers) { ___m_queuedAttackTimer = LastAttackTimer; ___m_queuedSecondAttackTimer = LastSecondaryAttackTimer; } } } public static ConfigEntry<bool> IsEnabled; public static ConfigEntry<bool> LoadOnStart; public static ConfigEntry<bool> AllowKick; public static ConfigEntry<bool> FallbackFisticuffs; public static ConfigEntry<bool> ToolbarEquipOnPunch; public static ConfigEntry<bool> UnsheatheAfterSwimming; public static ConfigEntry<bool> UnsheatheOnPunch; private readonly Harmony Harmony = new Harmony("com.riintouge.nounarmedcombat"); 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."); AllowKick = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "AllowKick", false, "Allow the player to kick."); FallbackFisticuffs = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "FallbackFisticuffs", true, "Allow the player to punch and kick when they have no weapon to equip."); ToolbarEquipOnPunch = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "ToolbarEquipOnPunch", true, "Instead of punching and if nothing is sheathed, equip gear from the toolbar, left to right."); UnsheatheAfterSwimming = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "UnsheatheAfterSwimming", false, "Unsheathe equipment when exiting water that was put away upon swimming."); UnsheatheOnPunch = ((BaseUnityPlugin)this).Config.Bind<bool>("1 - General", "UnsheatheOnPunch", true, "Instead of punching, equip sheathed equipment. Takes precedence over equipment on the toolbar."); if (LoadOnStart.Value) { Harmony.PatchAll(); } } }