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 WeaponSwitchQueue v1.0.3
Cjayride.WeaponSwitchQueue.dll
Decompiled 2 weeks agousing 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 HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("assembly_valheim")] [assembly: TargetFramework(".NETFramework,Version=v4.8.1", FrameworkDisplayName = ".NET Framework 4.8.1")] [assembly: AssemblyCompany("Cjayride.WeaponSwitchQueue")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.3.0")] [assembly: AssemblyInformationalVersion("1.0.3+a4e6cc71cac86ac4def8b82ccd81f00886c5838e")] [assembly: AssemblyProduct("Cjayride.WeaponSwitchQueue")] [assembly: AssemblyTitle("Cjayride.WeaponSwitchQueue")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.3.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 Cjayride.WeaponSwitchQueue { [HarmonyPatch(typeof(Player), "ToggleEquipped", new Type[] { typeof(ItemData) })] internal static class PlayerToggleEquippedPatch { private static void Postfix(Player __instance, bool __result, ItemData item) { if (Plugin.QueueWeaponChanges.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && __result && item != null && item.IsEquipable() && ((Character)__instance).InAttack()) { WeaponQueue.Enqueue(__instance, item); } } } [BepInPlugin("cjayride.weaponswitchqueue", "WeaponSwitchQueue", "1.0.3")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "cjayride.weaponswitchqueue"; public const string PluginName = "WeaponSwitchQueue"; public const string PluginVersion = "1.0.3"; internal static ConfigEntry<bool> QueueWeaponChanges; internal static ConfigEntry<bool> QueueHideWeapons; internal static ConfigEntry<bool> HideWithoutAnimation; internal static ConfigEntry<bool> InstantEquip; internal static ConfigEntry<float> QueueSeconds; internal static ConfigEntry<bool> DebugLogging; private static Plugin _instance; private void Awake() { //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Expected O, but got Unknown //IL_00e8: Unknown result type (might be due to invalid IL or missing references) _instance = this; QueueWeaponChanges = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "QueueWeaponChanges", true, "Hotbar weapon presses made during an attack animation are applied when the swing finishes."); QueueHideWeapons = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "QueueHideWeapons", true, "Pressing the sheath key during an attack hides your weapons when the swing finishes."); HideWithoutAnimation = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "HideWithoutAnimation", true, "Skip the sheath animation when a queued hide runs."); InstantEquip = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "InstantEquip", false, "Skip the equip time of the queued weapon. Off keeps the normal equip delay."); QueueSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("General", "QueueSeconds", 3f, new ConfigDescription("Forget a queued press if the attack has not ended within this many seconds.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 10f), Array.Empty<object>())); DebugLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DebugLogging", false, "Log every queued and applied switch to the BepInEx console."); new Harmony("cjayride.weaponswitchqueue").PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"WeaponSwitchQueue 1.0.3 loaded. Client only."); } private void Update() { Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { WeaponQueue.Clear(); } else if (!((Object)(object)((Character)localPlayer).m_nview == (Object)null) && ((Character)localPlayer).m_nview.IsValid() && ((Character)localPlayer).m_nview.IsOwner()) { if (QueueHideWeapons.Value && ((Character)localPlayer).InAttack() && ((Character)localPlayer).TakeInput() && (ZInput.GetButtonDown("Hide") || ZInput.GetButtonDown("JoyHide")) && (((Humanoid)localPlayer).GetRightItem() != null || ((Humanoid)localPlayer).GetLeftItem() != null)) { WeaponQueue.QueueHide(); } WeaponQueue.Tick(localPlayer, Time.deltaTime); } } internal static void Debug(string message) { if ((Object)(object)_instance != (Object)null && DebugLogging != null && DebugLogging.Value) { ((BaseUnityPlugin)_instance).Logger.LogInfo((object)message); } } } internal static class WeaponQueue { private static ItemData _pending; private static bool _wantEquipped; private static float _age; private static bool _hide; private static float _hideAge; internal static void Enqueue(Player player, ItemData item) { _pending = item; _wantEquipped = !((Humanoid)player).IsItemEquiped(item); _age = 0f; Plugin.Debug((_wantEquipped ? "Queued equip: " : "Queued unequip: ") + item.m_shared.m_name); } internal static void QueueHide() { _hide = true; _hideAge = 0f; Plugin.Debug("Queued hide"); } internal static void Clear() { _pending = null; _hide = false; } internal static void Tick(Player player, float dt) { float value = Plugin.QueueSeconds.Value; if (_pending != null) { _age += dt; if (_age > value) { Plugin.Debug("Dropped queued switch (timed out)"); _pending = null; } else if (!((Character)player).InAttack() && !((Character)player).InDodge()) { ItemData pending = _pending; bool wantEquipped = _wantEquipped; _pending = null; Apply(player, pending, wantEquipped); } } if (_hide) { _hideAge += dt; if (_hideAge > value) { _hide = false; } else if (!((Character)player).InAttack() && !((Character)player).InDodge()) { _hide = false; ((Humanoid)player).HideHandItems(false, !Plugin.HideWithoutAnimation.Value); Plugin.Debug("Applied queued hide"); } } } private static void Apply(Player player, ItemData item, bool wantEquipped) { if (item == null || ((Humanoid)player).m_inventory == null || !((Humanoid)player).m_inventory.ContainsItem(item)) { Plugin.Debug("Dropped queued switch (item gone)"); return; } if (((Humanoid)player).IsItemEquiped(item) == wantEquipped) { Plugin.Debug("Queued switch already satisfied"); return; } float equipDuration = item.m_shared.m_equipDuration; if (Plugin.InstantEquip.Value || ((Character)player).IsRunning()) { item.m_shared.m_equipDuration = 0f; } try { ((Humanoid)player).ToggleEquipped(item); } finally { item.m_shared.m_equipDuration = equipDuration; } Plugin.Debug("Applied queued switch: " + item.m_shared.m_name); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }