Decompiled source of FastSwap v1.0.14

FastSwap.dll

Decompiled 5 hours ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
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;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;
using UnityEngine.InputSystem.Utilities;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Skarif")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © Skarif")]
[assembly: AssemblyFileVersion("1.0.13.0")]
[assembly: AssemblyInformationalVersion("1.0.13")]
[assembly: AssemblyProduct("FastSwap")]
[assembly: AssemblyTitle("FastSwap")]
[assembly: AssemblyMetadata("Author", "Skarif")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.13.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 BetterSheathingMod
{
	[BepInPlugin("com.skarif.fastswap", "Better Sheathing and Mobility", "1.0.13")]
	public class BetterSheathingPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.skarif.fastswap";

		public const string PluginName = "Better Sheathing and Mobility";

		public const string PluginVersion = "1.0.13";

		public static ConfigEntry<bool> ModEnabled;

		public static ConfigEntry<float> SprintSheathStaminaCost;

		public static ConfigEntry<bool> AllowAttackCancelUnsheathe;

		public static ConfigEntry<bool> AllowWeaponSwitchWhileRunning;

		public static ConfigEntry<bool> LimitSlowdownRemovalToEquipmentAndConsumables;

		public static float UnsheatheTimer = 0f;

		public static bool OverrideMinorActionForAttack = false;

		private static int s_layer1EmptyStateHash = 0;

		public static readonly FieldRef<Character, Animator> GetAnimator = AccessTools.FieldRefAccess<Character, Animator>("m_animator");

		public static readonly FieldRef<Humanoid, ItemData> GetRightItem = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_rightItem");

		public static readonly FieldRef<Humanoid, ItemData> GetLeftItem = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_leftItem");

		public static readonly FieldRef<Humanoid, ItemData> GetHiddenRightItem = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_hiddenRightItem");

		public static readonly FieldRef<Humanoid, ItemData> GetHiddenLeftItem = AccessTools.FieldRefAccess<Humanoid, ItemData>("m_hiddenLeftItem");

		private void Awake()
		{
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			string text = Path.Combine(Paths.ConfigPath, "com.author.bettersheathing.cfg");
			if (!File.Exists(((BaseUnityPlugin)this).Config.ConfigFilePath) && File.Exists(text))
			{
				try
				{
					File.Copy(text, ((BaseUnityPlugin)this).Config.ConfigFilePath);
					((BaseUnityPlugin)this).Config.Reload();
				}
				catch (IOException ex)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not migrate legacy FastSwap config: " + ex.Message));
				}
				catch (UnauthorizedAccessException ex2)
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Could not migrate legacy FastSwap config: " + ex2.Message));
				}
			}
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Включить/выключить мод.");
			SprintSheathStaminaCost = ((BaseUnityPlugin)this).Config.Bind<float>("Balance", "SprintStaminaCost", 12f, "Затраты выносливости на убирание, доставание и смену оружия на бегу. / Stamina cost for sheathing, drawing and switching weapons while sprinting.");
			AllowAttackCancelUnsheathe = ((BaseUnityPlugin)this).Config.Bind<bool>("Features", "AllowAttackCancel", true, "Разрешить прерывать анимации доставания и смены оружия ударом или началом натяжения лука. / Allow attacks or starting a bow draw to interrupt weapon drawing and switching animations.");
			AllowWeaponSwitchWhileRunning = ((BaseUnityPlugin)this).Config.Bind<bool>("Features", "AllowWeaponSwitchWhileRunning", true, "Разрешить смену оружия во время бега. Инструменты (молоток, мотыга, культиватор, поднос и предметы с меню строительства) сохраняют поведение игры независимо от настройки. Убирание и доставание со спины не затрагиваются. / Allow switching weapons while sprinting. Tools (hammer, hoe, cultivator, serving tray and items with a build menu) keep vanilla behavior regardless of this setting. Sheathing/drawing from the back are unaffected.");
			LimitSlowdownRemovalToEquipmentAndConsumables = ((BaseUnityPlugin)this).Config.Bind<bool>("Features", "LimitSlowdownRemovalToEquipmentAndConsumables", true, "Убирать Slow Walk только при убирании/доставании оружия, смене экипировки и употреблении еды/зелий. Двери, сбор растений и другие взаимодействия сохраняют стандартное замедление. false возвращает прежнее снятие замедления со всех вспомогательных действий. / Remove Slow Walk only for sheathing/drawing, changing equipment and consuming food/potions. Doors, harvesting and other interactions retain vanilla slowdown. false restores the previous removal for all minor actions.");
			new Harmony("com.skarif.fastswap").PatchAll();
		}

		public static bool CanApplySprintStamina(Player player)
		{
			if ((Object)(object)player == (Object)null)
			{
				return false;
			}
			if (((Character)player).IsSwimming() || !((Character)player).IsOnGround())
			{
				return false;
			}
			return ((Character)player).IsRunning();
		}

		public static bool IsSprintRestrictedItem(ItemData item)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if (IsHandItem(item) && (int)item.m_shared.m_itemType != 19)
			{
				return (Object)(object)item.m_shared.m_buildPieces == (Object)null;
			}
			return false;
		}

		public static bool IsHandItem(ItemData item)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Invalid comparison between Unknown and I4
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Invalid comparison between Unknown and I4
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Invalid comparison between Unknown and I4
			if (item == null)
			{
				return false;
			}
			ItemType itemType = item.m_shared.m_itemType;
			if ((int)itemType <= 15)
			{
				if (itemType - 3 <= 2 || itemType - 14 <= 1)
				{
					goto IL_002f;
				}
			}
			else if ((int)itemType == 19 || (int)itemType == 22)
			{
				goto IL_002f;
			}
			return false;
			IL_002f:
			return true;
		}

		public static void ApplySprintStamina(Player player)
		{
			if (!CanApplySprintStamina(player))
			{
				return;
			}
			float num = Mathf.Max(0f, SprintSheathStaminaCost.Value);
			if (((Character)player).HaveStamina(num))
			{
				((Character)player).UseStamina(num);
				return;
			}
			Hud instance = Hud.instance;
			if (instance != null)
			{
				instance.StaminaBarEmptyFlash();
			}
			((Character)player).SetRun(false);
		}

		public static void ForceInterruptEquipHip(Player player)
		{
			UnsheatheTimer = 0f;
			Animator val = GetAnimator.Invoke((Character)(object)player);
			if ((Object)(object)val == (Object)null || val.layerCount <= 1)
			{
				return;
			}
			val.ResetTrigger("equip_hip");
			if (s_layer1EmptyStateHash == 0)
			{
				int num = Animator.StringToHash("Empty");
				if (val.HasState(1, num))
				{
					s_layer1EmptyStateHash = num;
				}
				else
				{
					s_layer1EmptyStateHash = Animator.StringToHash("None");
				}
			}
			if (s_layer1EmptyStateHash != 0)
			{
				val.Play(s_layer1EmptyStateHash, 1, 0f);
				val.Update(0f);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "ToggleEquipped")]
	public static class Patch_Player_ToggleEquipped
	{
		public struct ToggleState
		{
			public bool Track;

			public bool Queued;

			public bool Equipped;
		}

		[HarmonyPrefix]
		public static bool Prefix(Player __instance, ItemData item, ref bool __result, out ToggleState __state)
		{
			__state = default(ToggleState);
			if (!BetterSheathingPlugin.ModEnabled.Value || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !BetterSheathingPlugin.IsSprintRestrictedItem(item))
			{
				return true;
			}
			__result = true;
			if (!BetterSheathingPlugin.AllowWeaponSwitchWhileRunning.Value && ((Character)__instance).IsRunning())
			{
				return false;
			}
			if (((Character)__instance).InAttack() || ((Character)__instance).InDodge() || ((Character)__instance).IsDead())
			{
				return false;
			}
			__state = new ToggleState
			{
				Track = true,
				Queued = __instance.IsEquipActionQueued(item),
				Equipped = ((Humanoid)__instance).IsItemEquiped(item)
			};
			return true;
		}

		[HarmonyPostfix]
		public static void Postfix(Player __instance, ItemData item, bool __result, ToggleState __state)
		{
			if (__result && __state.Track && ((!__state.Queued && __instance.IsEquipActionQueued(item)) || __state.Equipped != ((Humanoid)__instance).IsItemEquiped(item)))
			{
				BetterSheathingPlugin.ApplySprintStamina(__instance);
			}
		}
	}
	public static class HandEquipmentAttackCancel
	{
		private static readonly FieldRef<Player, List<MinorActionData>> GetActionQueue = AccessTools.FieldRefAccess<Player, List<MinorActionData>>("m_actionQueue");

		private static readonly FieldRef<Player, string> GetActionAnimation = AccessTools.FieldRefAccess<Player, string>("m_actionAnimation");

		private static readonly FieldRef<Character, ZSyncAnimation> GetZanim = AccessTools.FieldRefAccess<Character, ZSyncAnimation>("m_zanim");

		public static bool CanInterrupt(Player player)
		{
			if (!((Character)player).InAttack() && !((Character)player).InDodge() && !((Character)player).IsDead() && ((Character)player).CanMove() && !((Character)player).IsKnockedBack())
			{
				return !((Character)player).IsStaggering();
			}
			return false;
		}

		public static bool TryComplete(Player player)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Invalid comparison between Unknown and I4
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			List<MinorActionData> list = GetActionQueue.Invoke(player);
			if (list.Count == 0)
			{
				return false;
			}
			MinorActionData val = list[0];
			if (!BetterSheathingPlugin.IsHandItem(val.m_item) || ((int)val.m_type != 0 && (int)val.m_type != 1))
			{
				return false;
			}
			Animator val2 = BetterSheathingPlugin.GetAnimator.Invoke((Character)(object)player);
			if ((Object)(object)val2 != (Object)null && val2.layerCount > 1 && (IsOtherMinorAction(val2.GetCurrentAnimatorStateInfo(1)) || (val2.IsInTransition(1) && IsOtherMinorAction(val2.GetNextAnimatorStateInfo(1)))))
			{
				return false;
			}
			if ((int)val.m_type == 0)
			{
				if (!((Humanoid)player).EquipItem(val.m_item, true))
				{
					return false;
				}
			}
			else
			{
				((Humanoid)player).UnequipItem(val.m_item, true);
			}
			list.Remove(val);
			ZSyncAnimation obj = GetZanim.Invoke((Character)(object)player);
			if (obj != null)
			{
				obj.SetBool("equipping", false);
			}
			if (GetActionAnimation.Invoke(player) == "equipping")
			{
				GetActionAnimation.Invoke(player) = null;
			}
			return true;
		}

		private static bool IsOtherMinorAction(AnimatorStateInfo state)
		{
			if (((AnimatorStateInfo)(ref state)).tagHash == Animator.StringToHash("minoraction") && ((AnimatorStateInfo)(ref state)).shortNameHash != Animator.StringToHash("Changing equipment") && ((AnimatorStateInfo)(ref state)).shortNameHash != Animator.StringToHash("EquipExit"))
			{
				return ((AnimatorStateInfo)(ref state)).shortNameHash != Animator.StringToHash("equip_hip");
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Player), "PlayerAttackInput")]
	public static class Patch_Player_PlayerAttackInput
	{
		[HarmonyPrefix]
		public static void Prefix(Player __instance, bool ___m_attack, bool ___m_attackHold, bool ___m_secondaryAttack, bool ___m_secondaryAttackHold)
		{
			if (BetterSheathingPlugin.ModEnabled.Value && BetterSheathingPlugin.AllowAttackCancelUnsheathe.Value && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && (___m_attack || ___m_attackHold || ___m_secondaryAttack || ___m_secondaryAttackHold) && HandEquipmentAttackCancel.CanInterrupt(__instance) && HandEquipmentAttackCancel.TryComplete(__instance))
			{
				BetterSheathingPlugin.ForceInterruptEquipHip(__instance);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "CheckRun")]
	public static class Patch_Player_CheckRun
	{
		private static readonly FieldRef<Player, List<MinorActionData>> GetActionQueue = AccessTools.FieldRefAccess<Player, List<MinorActionData>>("m_actionQueue");

		[HarmonyTranspiler]
		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = new List<CodeInstruction>(instructions);
			MethodInfo objB = AccessTools.Method(typeof(Humanoid), "ClearActionQueue", (Type[])null, (Type[])null);
			MethodInfo operand = AccessTools.Method(typeof(Patch_Player_CheckRun), "ClearActionQueueForRun", (Type[])null, (Type[])null);
			int num = 0;
			foreach (CodeInstruction item in list)
			{
				if ((item.opcode == OpCodes.Callvirt || item.opcode == OpCodes.Call) && object.Equals(item.operand, objB))
				{
					item.opcode = OpCodes.Call;
					item.operand = operand;
					num++;
				}
			}
			if (num != 1)
			{
				throw new InvalidOperationException("FastSwap: expected one CheckRun queue-clear call, found " + num);
			}
			return list;
		}

		public static void ClearActionQueueForRun(Player player)
		{
			List<MinorActionData> list = GetActionQueue.Invoke(player);
			if (!BetterSheathingPlugin.ModEnabled.Value || !BetterSheathingPlugin.AllowWeaponSwitchWhileRunning.Value || (Object)(object)player != (Object)(object)Player.m_localPlayer)
			{
				list.Clear();
				return;
			}
			list.RemoveAll((MinorActionData action) => ((int)action.m_type != 0 && (int)action.m_type != 1) || !BetterSheathingPlugin.IsHandItem(action.m_item));
		}
	}
	[HarmonyPatch(typeof(ZInput), "GetButtonDown")]
	public static class Patch_ZInput_GetButtonDown
	{
		[HarmonyPostfix]
		public static void Postfix(string name, ref bool __result)
		{
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			if (__result || name == null || !name.StartsWith("Hotbar") || (name.Length != 7 && name.Length != 10) || name[6] < '1' || name[6] > '8' || (name.Length == 10 && !name.EndsWith("Alt")) || !BetterSheathingPlugin.ModEnabled.Value || !BetterSheathingPlugin.AllowWeaponSwitchWhileRunning.Value || (Object)(object)Player.m_localPlayer == (Object)null || (!ZInput.GetButton("Run") && !ZInput.GetKey((KeyCode)304, true) && !ZInput.GetKey((KeyCode)303, true)))
			{
				return;
			}
			ZInput instance = ZInput.instance;
			object obj;
			if (instance == null)
			{
				obj = null;
			}
			else
			{
				ButtonDef buttonDef = instance.GetButtonDef(name);
				obj = ((buttonDef != null) ? buttonDef.ButtonAction : null);
			}
			InputAction val = (InputAction)obj;
			if (val == null || !val.enabled)
			{
				return;
			}
			Enumerator<InputBinding> enumerator = val.bindings.GetEnumerator();
			try
			{
				while (enumerator.MoveNext())
				{
					InputBinding current = enumerator.Current;
					if (!((InputBinding)(ref current)).isComposite && !((InputBinding)(ref current)).isPartOfComposite && !string.IsNullOrEmpty(((InputBinding)(ref current)).effectivePath))
					{
						InputControl obj2 = InputSystem.FindControl(((InputBinding)(ref current)).effectivePath);
						KeyControl val2 = (KeyControl)(object)((obj2 is KeyControl) ? obj2 : null);
						if (val2 != null && ((ButtonControl)val2).wasPressedThisFrame)
						{
							__result = true;
							break;
						}
					}
				}
			}
			finally
			{
				((IDisposable)enumerator/*cast due to .constrained prefix*/).Dispose();
			}
		}
	}
	[HarmonyPatch(typeof(Player), "InMinorActionSlowdown")]
	public static class Patch_Player_InMinorActionSlowdown
	{
		private static readonly int MinorActionTag = Animator.StringToHash("minoraction");

		private static readonly int EquipHip = Animator.StringToHash("equip_hip");

		private static readonly int EquipHead = Animator.StringToHash("equip_head");

		private static readonly int ChangingEquipment = Animator.StringToHash("Changing equipment");

		private static readonly int EquipExit = Animator.StringToHash("EquipExit");

		private static readonly int Eat = Animator.StringToHash("eat");

		[HarmonyPostfix]
		public static void Postfix(Player __instance, ref bool __result)
		{
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			if (!__result || !BetterSheathingPlugin.ModEnabled.Value || (Object)(object)__instance != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			if (!BetterSheathingPlugin.LimitSlowdownRemovalToEquipmentAndConsumables.Value)
			{
				__result = false;
				return;
			}
			Animator val = BetterSheathingPlugin.GetAnimator.Invoke((Character)(object)__instance);
			if (!((Object)(object)val == (Object)null) && val.layerCount > 1)
			{
				__result = ShouldKeepSlowdown(val.GetCurrentAnimatorStateInfo(1)) || (val.IsInTransition(1) && ShouldKeepSlowdown(val.GetNextAnimatorStateInfo(1)));
			}
		}

		private static bool ShouldKeepSlowdown(AnimatorStateInfo state)
		{
			if (((AnimatorStateInfo)(ref state)).tagHash != MinorActionTag)
			{
				return false;
			}
			int shortNameHash = ((AnimatorStateInfo)(ref state)).shortNameHash;
			if (shortNameHash != EquipHip && shortNameHash != EquipHead && shortNameHash != ChangingEquipment && shortNameHash != EquipExit)
			{
				return shortNameHash != Eat;
			}
			return false;
		}
	}
	[HarmonyPatch(typeof(Humanoid), "HideHandItems")]
	public static class Patch_Humanoid_HideHandItems
	{
		[HarmonyPrefix]
		public static void Prefix(Humanoid __instance)
		{
			if (!BetterSheathingPlugin.ModEnabled.Value)
			{
				return;
			}
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val == null || !((Object)(object)val == (Object)(object)Player.m_localPlayer) || (BetterSheathingPlugin.GetRightItem.Invoke((Humanoid)(object)val) == null && BetterSheathingPlugin.GetLeftItem.Invoke((Humanoid)(object)val) == null) || !BetterSheathingPlugin.CanApplySprintStamina(val))
			{
				return;
			}
			float value = BetterSheathingPlugin.SprintSheathStaminaCost.Value;
			if (((Character)val).HaveStamina(value))
			{
				((Character)val).UseStamina(value);
				return;
			}
			Hud instance = Hud.instance;
			if (instance != null)
			{
				instance.StaminaBarEmptyFlash();
			}
			((Character)val).SetRun(false);
		}
	}
	[HarmonyPatch(typeof(Humanoid), "ShowHandItems")]
	public static class Patch_Humanoid_ShowHandItems
	{
		[HarmonyPrefix]
		public static void Prefix(Humanoid __instance)
		{
			if (!BetterSheathingPlugin.ModEnabled.Value)
			{
				return;
			}
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (val == null || !((Object)(object)val == (Object)(object)Player.m_localPlayer) || (BetterSheathingPlugin.GetHiddenRightItem.Invoke((Humanoid)(object)val) == null && BetterSheathingPlugin.GetHiddenLeftItem.Invoke((Humanoid)(object)val) == null))
			{
				return;
			}
			if (BetterSheathingPlugin.CanApplySprintStamina(val))
			{
				float value = BetterSheathingPlugin.SprintSheathStaminaCost.Value;
				if (((Character)val).HaveStamina(value))
				{
					((Character)val).UseStamina(value);
				}
				else
				{
					Hud instance = Hud.instance;
					if (instance != null)
					{
						instance.StaminaBarEmptyFlash();
					}
					((Character)val).SetRun(false);
				}
			}
			BetterSheathingPlugin.UnsheatheTimer = 1.2f;
		}
	}
	[HarmonyPatch(typeof(Humanoid), "StartAttack")]
	public static class Patch_Humanoid_StartAttack
	{
		[HarmonyPrefix]
		public static void Prefix(Humanoid __instance)
		{
			if (BetterSheathingPlugin.ModEnabled.Value && BetterSheathingPlugin.AllowAttackCancelUnsheathe.Value)
			{
				Player val = (Player)(object)((__instance is Player) ? __instance : null);
				if (val != null && (Object)(object)val == (Object)(object)Player.m_localPlayer && HandEquipmentAttackCancel.CanInterrupt(val) && (HandEquipmentAttackCancel.TryComplete(val) || !(BetterSheathingPlugin.UnsheatheTimer <= 0f)))
				{
					BetterSheathingPlugin.OverrideMinorActionForAttack = true;
					BetterSheathingPlugin.ForceInterruptEquipHip(val);
				}
			}
		}

		[HarmonyPostfix]
		public static void Postfix(Humanoid __instance, bool __result)
		{
			BetterSheathingPlugin.OverrideMinorActionForAttack = false;
			if (__result && __instance is Player)
			{
				BetterSheathingPlugin.UnsheatheTimer = 0f;
			}
		}
	}
	[HarmonyPatch(typeof(Player), "UpdateAttackBowDraw")]
	public static class Patch_Player_UpdateAttackBowDraw
	{
		private static readonly int MinorAction = Animator.StringToHash("minoraction");

		private static readonly int MinorActionFast = Animator.StringToHash("minoraction_fast");

		private static readonly int EquipHip = Animator.StringToHash("equip_hip");

		[HarmonyPrefix]
		public static void Prefix(Player __instance, bool ___m_attackHold, bool ___m_blocking, ref float ___m_attackDrawTime, out bool __state)
		{
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			__state = BetterSheathingPlugin.OverrideMinorActionForAttack;
			if (!BetterSheathingPlugin.ModEnabled.Value || !BetterSheathingPlugin.AllowAttackCancelUnsheathe.Value || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || !___m_attackHold || ___m_blocking || ((Character)__instance).IsAttached() || BetterSheathingPlugin.UnsheatheTimer <= 0f || !HandEquipmentAttackCancel.CanInterrupt(__instance))
			{
				return;
			}
			Animator val = BetterSheathingPlugin.GetAnimator.Invoke((Character)(object)__instance);
			if (!((Object)(object)val == (Object)null) && val.layerCount > 1 && !IsOtherAction(val.GetCurrentAnimatorStateInfo(1)) && (!val.IsInTransition(1) || !IsOtherAction(val.GetNextAnimatorStateInfo(1))))
			{
				BetterSheathingPlugin.ForceInterruptEquipHip(__instance);
				BetterSheathingPlugin.OverrideMinorActionForAttack = true;
				if (___m_attackDrawTime < 0f)
				{
					___m_attackDrawTime = 0f;
				}
			}
		}

		private static bool IsOtherAction(AnimatorStateInfo state)
		{
			if (((AnimatorStateInfo)(ref state)).tagHash == MinorAction || ((AnimatorStateInfo)(ref state)).tagHash == MinorActionFast)
			{
				return ((AnimatorStateInfo)(ref state)).shortNameHash != EquipHip;
			}
			return false;
		}

		[HarmonyPostfix]
		public static void Postfix(bool __state)
		{
			BetterSheathingPlugin.OverrideMinorActionForAttack = __state;
		}

		[HarmonyFinalizer]
		public static void Finalizer(bool __state)
		{
			BetterSheathingPlugin.OverrideMinorActionForAttack = __state;
		}
	}
	[HarmonyPatch(typeof(Player), "InMinorAction")]
	public static class Patch_Player_InMinorAction
	{
		[HarmonyPrefix]
		public static bool Prefix(ref bool __result)
		{
			if (BetterSheathingPlugin.OverrideMinorActionForAttack)
			{
				__result = false;
				return false;
			}
			return true;
		}
	}
	[HarmonyPatch(typeof(Player), "Update")]
	public static class Patch_Player_Update
	{
		[HarmonyPostfix]
		public static void Postfix(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && BetterSheathingPlugin.UnsheatheTimer > 0f)
			{
				BetterSheathingPlugin.UnsheatheTimer -= Time.deltaTime;
			}
		}
	}
}