Decompiled source of Toggle Melee Stance v1.0.0

Toggle Melee Stance.dll

Decompiled a day ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using UnityEngine;
using UnityEngine.InputSystem;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Toggle Melee Stance")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Toggle Melee Stance")]
[assembly: AssemblyCopyright("Copyright ©  2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("a7db406a-f689-4a93-87dd-978986c6f891")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ToggleMeleeStance;

[BepInPlugin("kumo.sulfur.toggle_melee_stance", "Toggle Melee Stance", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public sealed class Plugin : BaseUnityPlugin
{
	private sealed class ToggleState
	{
		public bool IsToggled;

		public bool AttackInProgress;

		public bool SheatheAfterAttack;

		public bool SuppressMeleeUntilReleased;

		public float NextChargeAttemptTime;
	}

	private sealed class SafeAnimatorState
	{
		public bool Valid;

		public int FullPathHash;

		public int ShortNameHash;

		public string ClipName;
	}

	public const string PluginGuid = "kumo.sulfur.toggle_melee_stance";

	public const string PluginName = "Toggle Melee Stance";

	public const string PluginVersion = "1.0.0";

	public const string MeleeExpansionGuid = "kumo.sulfur.melee_expansion";

	internal static ManualLogSource Log;

	internal static ConfigEntry<bool> EnableMod;

	internal static ConfigEntry<bool> FirePerformsMeleeAttack;

	internal static ConfigEntry<bool> ResetMeleeAnimatorBeforeSheathe;

	internal static ConfigEntry<bool> DisableWhenMeleeExpansionDetected;

	internal static ConfigEntry<float> ReChargeRetryInterval;

	internal static ConfigEntry<bool> LogStateChanges;

	private Harmony harmony;

	private static Type equipmentManagerType;

	private static Type weaponType;

	private static MethodInfo mHandleAimInput;

	private static MethodInfo mHandleMeleeInput;

	private static MethodInfo mPullTrigger;

	private static MethodInfo mReleaseTrigger;

	private static MethodInfo mChargeBasicMelee;

	private static MethodInfo mUseBasicMelee;

	private static MethodInfo mOnMeleeDone;

	private static MethodInfo mReportMeleeDone;

	private static MethodInfo mIsMeleeCharging;

	private static MethodInfo mChargeMelee;

	private static MethodInfo mSetAlternativeState;

	private static PropertyInfo pIsMelee;

	private static PropertyInfo pAnimator;

	private static FieldInfo fAltFireAction;

	private static FieldInfo fMeleeFireAction;

	private static FieldInfo fMeleeFireActionAlternative;

	private static FieldInfo fCurrentHoldable;

	private static FieldInfo fEquipmentManager;

	private static FieldInfo fIsInMeleeCharge;

	private static FieldInfo fMeleePressed;

	private static FieldInfo fAlternativeMeleePressed;

	private static FieldInfo fAimingInputHeld;

	private static FieldInfo fMeleeInputCooldown;

	private static FieldInfo fCurrentParries;

	private static readonly ConditionalWeakTable<object, ToggleState> States = new ConditionalWeakTable<object, ToggleState>();

	private static readonly ConditionalWeakTable<object, SafeAnimatorState> SafeAnimatorStates = new ConditionalWeakTable<object, SafeAnimatorState>();

	private void Awake()
	{
		//IL_007a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0084: Expected O, but got Unknown
		//IL_014b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0155: Expected O, but got Unknown
		Log = ((BaseUnityPlugin)this).Logger;
		EnableMod = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableMod", true, "Enable Toggle Melee Stance.");
		FirePerformsMeleeAttack = ((BaseUnityPlugin)this).Config.Bind<bool>("Melee", "FirePerformsMeleeAttack", true, "When melee stance is toggled on, pressing the normal Fire action performs one melee attack.");
		ReChargeRetryInterval = ((BaseUnityPlugin)this).Config.Bind<float>("Melee", "ReChargeRetryInterval", 0.08f, new ConfigDescription("Seconds between retry attempts when the mod tries to re-enter melee charge after an attack.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.01f, 0.5f), Array.Empty<object>()));
		ResetMeleeAnimatorBeforeSheathe = ((BaseUnityPlugin)this).Config.Bind<bool>("Visual", "ResetMeleeAnimatorBeforeSheathe", true, "Before sheathing a toggled melee weapon, reset its Animator to the cached safe equip state. This prevents stale idle states from causing a slash-frame flash on the next draw.");
		DisableWhenMeleeExpansionDetected = ((BaseUnityPlugin)this).Config.Bind<bool>("Compatibility", "DisableWhenMeleeExpansionDetected", true, "Disable this standalone mod when kumo.sulfur.melee_expansion is installed.");
		LogStateChanges = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "LogStateChanges", false, "Log toggle melee state changes. Keep false for normal gameplay.");
		if (DisableWhenMeleeExpansionDetected.Value && Chainloader.PluginInfos.ContainsKey("kumo.sulfur.melee_expansion"))
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Melee Expansion detected. Toggle Melee Stance will stay disabled.");
			return;
		}
		if (!InitializeReflection())
		{
			((BaseUnityPlugin)this).Logger.LogError((object)"Reflection initialization failed. Mod will not patch.");
			return;
		}
		harmony = new Harmony("kumo.sulfur.toggle_melee_stance");
		Patch(mHandleAimInput, "HandleAimInputPrefix");
		Patch(mHandleMeleeInput, "HandleMeleeInputPrefix");
		Patch(mPullTrigger, "PullTriggerPrefix");
		Patch(mReleaseTrigger, "ReleaseTriggerPrefix");
		Patch(mReportMeleeDone, "ReportMeleeDonePrefix", "ReportMeleeDonePostfix");
		Patch(mChargeMelee, null, "ChargeMeleePostfix");
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Toggle Melee Stance loaded.");
	}

	private void OnDestroy()
	{
		Harmony obj = harmony;
		if (obj != null)
		{
			obj.UnpatchSelf();
		}
	}

	private static bool InitializeReflection()
	{
		equipmentManagerType = AccessTools.TypeByName("PerfectRandom.Sulfur.Core.Items.EquipmentManager");
		weaponType = AccessTools.TypeByName("PerfectRandom.Sulfur.Core.Weapons.Weapon");
		if (equipmentManagerType == null)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)"Could not find EquipmentManager type.");
			}
			return false;
		}
		if (weaponType == null)
		{
			ManualLogSource log2 = Log;
			if (log2 != null)
			{
				log2.LogError((object)"Could not find Weapon type.");
			}
			return false;
		}
		mHandleAimInput = AccessTools.Method(equipmentManagerType, "HandleAimInput", new Type[1] { typeof(bool) }, (Type[])null);
		mHandleMeleeInput = AccessTools.Method(equipmentManagerType, "HandleMeleeInput", new Type[1] { typeof(bool) }, (Type[])null);
		mPullTrigger = AccessTools.Method(equipmentManagerType, "PullTrigger", (Type[])null, (Type[])null);
		mReleaseTrigger = AccessTools.Method(equipmentManagerType, "ReleaseTrigger", (Type[])null, (Type[])null);
		mChargeBasicMelee = AccessTools.Method(equipmentManagerType, "ChargeBasicMelee", (Type[])null, (Type[])null);
		mUseBasicMelee = AccessTools.Method(equipmentManagerType, "UseBasicMelee", (Type[])null, (Type[])null);
		mOnMeleeDone = AccessTools.Method(equipmentManagerType, "OnMeleeDone", (Type[])null, (Type[])null);
		mReportMeleeDone = AccessTools.Method(weaponType, "ReportMeleeDone", (Type[])null, (Type[])null);
		mIsMeleeCharging = AccessTools.Method(weaponType, "IsMeleeCharging", (Type[])null, (Type[])null);
		mChargeMelee = AccessTools.Method(weaponType, "ChargeMelee", new Type[1] { typeof(bool) }, (Type[])null);
		mSetAlternativeState = AccessTools.Method(weaponType, "SetAlternativeState", new Type[1] { typeof(int) }, (Type[])null);
		pIsMelee = AccessTools.Property(weaponType, "IsMelee");
		pAnimator = FindPropertyRecursive(weaponType, "Animator");
		fAltFireAction = FindFieldRecursive(equipmentManagerType, "altFireAction");
		fMeleeFireAction = FindFieldRecursive(equipmentManagerType, "meleeFireAction");
		fMeleeFireActionAlternative = FindFieldRecursive(equipmentManagerType, "meleeFireActionAlternative");
		fCurrentHoldable = FindFieldRecursive(equipmentManagerType, "currentHoldable");
		fEquipmentManager = FindFieldRecursive(weaponType, "equipmentManager");
		fIsInMeleeCharge = FindFieldRecursive(equipmentManagerType, "<isInMeleeCharge>k__BackingField", "isInMeleeCharge");
		fMeleePressed = FindFieldRecursive(equipmentManagerType, "<meleePressed>k__BackingField", "meleePressed");
		fAlternativeMeleePressed = FindFieldRecursive(equipmentManagerType, "<alternativeMeleePressed>k__BackingField", "alternativeMeleePressed");
		fAimingInputHeld = FindFieldRecursive(equipmentManagerType, "<AimingInputHeld>k__BackingField", "AimingInputHeld");
		fMeleeInputCooldown = FindFieldRecursive(equipmentManagerType, "meleeInputCooldown");
		fCurrentParries = FindFieldRecursive(weaponType, "currentParries");
		return Require(mHandleAimInput, "EquipmentManager.HandleAimInput(bool)") && Require(mHandleMeleeInput, "EquipmentManager.HandleMeleeInput(bool)") && Require(mPullTrigger, "EquipmentManager.PullTrigger()") && Require(mReleaseTrigger, "EquipmentManager.ReleaseTrigger()") && Require(mChargeBasicMelee, "EquipmentManager.ChargeBasicMelee()") && Require(mUseBasicMelee, "EquipmentManager.UseBasicMelee()") && Require(mOnMeleeDone, "EquipmentManager.OnMeleeDone()") && Require(mReportMeleeDone, "Weapon.ReportMeleeDone()") && Require(mIsMeleeCharging, "Weapon.IsMeleeCharging()") && Require(mChargeMelee, "Weapon.ChargeMelee(bool)") && Require(mSetAlternativeState, "Weapon.SetAlternativeState(int)") && Require(pIsMelee, "Weapon.IsMelee") && Require(pAnimator, "Holdable.Animator") && Require(fAltFireAction, "EquipmentManager.altFireAction") && Require(fMeleeFireAction, "EquipmentManager.meleeFireAction") && Require(fMeleeFireActionAlternative, "EquipmentManager.meleeFireActionAlternative") && Require(fCurrentHoldable, "EquipmentManager.currentHoldable") && Require(fEquipmentManager, "Weapon.equipmentManager") && Require(fIsInMeleeCharge, "EquipmentManager.isInMeleeCharge") && Require(fMeleePressed, "EquipmentManager.meleePressed") && Require(fAlternativeMeleePressed, "EquipmentManager.alternativeMeleePressed") && Require(fAimingInputHeld, "EquipmentManager.AimingInputHeld") && Require(fMeleeInputCooldown, "EquipmentManager.meleeInputCooldown");
	}

	private static bool Require(MemberInfo member, string name)
	{
		if (member != null)
		{
			return true;
		}
		ManualLogSource log = Log;
		if (log != null)
		{
			log.LogError((object)("Missing required member: " + name));
		}
		return false;
	}

	private void Patch(MethodInfo original, string prefix = null, string postfix = null)
	{
		//IL_0025: Unknown result type (might be due to invalid IL or missing references)
		//IL_002b: Expected O, but got Unknown
		//IL_004c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0052: Expected O, but got Unknown
		HarmonyMethod val = null;
		HarmonyMethod val2 = null;
		if (!string.IsNullOrEmpty(prefix))
		{
			val = new HarmonyMethod(AccessTools.Method(typeof(Plugin), prefix, (Type[])null, (Type[])null));
		}
		if (!string.IsNullOrEmpty(postfix))
		{
			val2 = new HarmonyMethod(AccessTools.Method(typeof(Plugin), postfix, (Type[])null, (Type[])null));
		}
		harmony.Patch((MethodBase)original, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
	}

	private static FieldInfo FindFieldRecursive(Type type, params string[] names)
	{
		Type type2 = type;
		while (type2 != null)
		{
			foreach (string text in names)
			{
				FieldInfo fieldInfo = AccessTools.Field(type2, text);
				if (fieldInfo != null)
				{
					return fieldInfo;
				}
			}
			type2 = type2.BaseType;
		}
		return null;
	}

	private static PropertyInfo FindPropertyRecursive(Type type, string name)
	{
		Type type2 = type;
		while (type2 != null)
		{
			PropertyInfo propertyInfo = AccessTools.Property(type2, name);
			if (propertyInfo != null)
			{
				return propertyInfo;
			}
			type2 = type2.BaseType;
		}
		return null;
	}

	private static ToggleState GetState(object equipmentManager)
	{
		return States.GetValue(equipmentManager, (object _) => new ToggleState());
	}

	private static bool IsModActive()
	{
		return EnableMod != null && EnableMod.Value;
	}

	private static void HandleAimInputPrefix(object __instance, ref bool holdingMeleeAction)
	{
		if (IsModActive())
		{
			ToggleState state = GetState(__instance);
			if (state.IsToggled)
			{
				holdingMeleeAction = true;
			}
		}
	}

	private static bool HandleMeleeInputPrefix(object __instance, bool holdingMeleeAction)
	{
		if (!IsModActive())
		{
			return true;
		}
		ToggleState state = GetState(__instance);
		if (state.SuppressMeleeUntilReleased)
		{
			if (IsMeleeHeld(__instance))
			{
				return false;
			}
			state.SuppressMeleeUntilReleased = false;
			if (LogStateChanges.Value)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)"Melee input released after manual sheathe. Input suppression cleared.");
				}
			}
			return false;
		}
		bool flag = WasMeleePressedThisFrame(__instance);
		if (!state.IsToggled && IsAimingInputHeld(__instance) && holdingMeleeAction)
		{
			return true;
		}
		if (!state.IsToggled && IsMeleeInputCoolingDown(__instance))
		{
			return true;
		}
		if (flag)
		{
			if (!state.IsToggled)
			{
				ToggleOn(__instance, state);
				return false;
			}
			ToggleOff(__instance, state);
			return false;
		}
		if (state.IsToggled)
		{
			MaintainToggledMelee(__instance, state);
			return false;
		}
		return true;
	}

	private static bool PullTriggerPrefix(object __instance)
	{
		if (!IsModActive())
		{
			return true;
		}
		ToggleState state = GetState(__instance);
		if (!state.IsToggled)
		{
			return true;
		}
		if (!FirePerformsMeleeAttack.Value)
		{
			return false;
		}
		object currentHoldable = GetCurrentHoldable(__instance);
		if (!IsMeleeWeapon(currentHoldable))
		{
			MaintainToggledMelee(__instance, state);
			return false;
		}
		if (!IsMeleeCharging(currentHoldable))
		{
			MaintainToggledMelee(__instance, state);
			return false;
		}
		if (state.AttackInProgress)
		{
			return false;
		}
		state.AttackInProgress = true;
		state.SheatheAfterAttack = false;
		state.SuppressMeleeUntilReleased = false;
		if (LogStateChanges.Value)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)"Fire action converted to melee attack.");
			}
		}
		InvokeUseBasicMelee(__instance);
		return false;
	}

	private static bool ReleaseTriggerPrefix(object __instance)
	{
		if (!IsModActive())
		{
			return true;
		}
		ToggleState state = GetState(__instance);
		if (!state.IsToggled && !state.AttackInProgress && !state.SheatheAfterAttack)
		{
			return true;
		}
		return false;
	}

	private static void ReportMeleeDonePrefix(object __instance)
	{
		if (!IsModActive())
		{
			return;
		}
		object equipmentManagerFromWeapon = GetEquipmentManagerFromWeapon(__instance);
		if (equipmentManagerFromWeapon != null)
		{
			ToggleState state = GetState(equipmentManagerFromWeapon);
			if (state.IsToggled || state.AttackInProgress || state.SheatheAfterAttack)
			{
				PrepareMeleeAnimatorForFutureDraw(__instance);
			}
		}
	}

	private static void ReportMeleeDonePostfix(object __instance)
	{
		if (!IsModActive())
		{
			return;
		}
		object equipmentManagerFromWeapon = GetEquipmentManagerFromWeapon(__instance);
		if (equipmentManagerFromWeapon == null)
		{
			return;
		}
		ToggleState state = GetState(equipmentManagerFromWeapon);
		if (state.SheatheAfterAttack)
		{
			state.AttackInProgress = false;
			state.SheatheAfterAttack = false;
			state.IsToggled = false;
			state.SuppressMeleeUntilReleased = true;
			state.NextChargeAttemptTime = 0f;
			if (LogStateChanges.Value)
			{
				ManualLogSource log = Log;
				if (log != null)
				{
					log.LogInfo((object)"Melee attack finished. Staying sheathed.");
				}
			}
			return;
		}
		if (!state.IsToggled)
		{
			state.AttackInProgress = false;
			state.NextChargeAttemptTime = 0f;
			return;
		}
		state.AttackInProgress = false;
		state.NextChargeAttemptTime = Time.time + ClampRetryInterval();
		if (LogStateChanges.Value)
		{
			ManualLogSource log2 = Log;
			if (log2 != null)
			{
				log2.LogInfo((object)"Melee attack finished. Re-entering toggled melee stance.");
			}
		}
		InvokeChargeBasicMelee(equipmentManagerFromWeapon);
	}

	private static void ChargeMeleePostfix(object __instance, bool state)
	{
		if (IsModActive() && state)
		{
			CacheSafeMeleeAnimatorStateIfUseful(__instance, "ChargeMelee(true)");
		}
	}

	private static void ToggleOn(object equipmentManager, ToggleState state)
	{
		state.IsToggled = true;
		state.AttackInProgress = false;
		state.SheatheAfterAttack = false;
		state.SuppressMeleeUntilReleased = false;
		state.NextChargeAttemptTime = Time.time + ClampRetryInterval();
		if (LogStateChanges.Value)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)"Toggle melee ON.");
			}
		}
		InvokeChargeBasicMelee(equipmentManager);
		SetMeleePressed(equipmentManager, value: true);
	}

	private static void ToggleOff(object equipmentManager, ToggleState state)
	{
		if (LogStateChanges.Value)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)"Toggle melee OFF.");
			}
		}
		state.IsToggled = false;
		state.NextChargeAttemptTime = 0f;
		state.SuppressMeleeUntilReleased = true;
		SetAlternativeMeleePressed(equipmentManager, value: false);
		SetMeleePressed(equipmentManager, value: false);
		object currentHoldable = GetCurrentHoldable(equipmentManager);
		if (state.AttackInProgress)
		{
			state.SheatheAfterAttack = true;
			if (LogStateChanges.Value)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogInfo((object)"Melee attack is in progress. Will sheathe after current attack finishes.");
				}
			}
		}
		else
		{
			state.AttackInProgress = false;
			state.SheatheAfterAttack = false;
			CleanCurrentMeleeWeaponState(currentHoldable);
			InvokeOnMeleeDone(equipmentManager);
		}
	}

	private static void MaintainToggledMelee(object equipmentManager, ToggleState state)
	{
		if (!state.AttackInProgress && !state.SheatheAfterAttack)
		{
			bool flag = IsAltFirePressed(equipmentManager);
			SetAlternativeMeleePressed(equipmentManager, flag);
			UpdateCurrentMeleeAlternativeAnimator(equipmentManager, flag);
			if (!IsInMeleeCharge(equipmentManager) && !(Time.time < state.NextChargeAttemptTime))
			{
				state.NextChargeAttemptTime = Time.time + ClampRetryInterval();
				InvokeChargeBasicMelee(equipmentManager);
				SetMeleePressed(equipmentManager, value: true);
			}
		}
	}

	private static void CacheSafeMeleeAnimatorStateIfUseful(object weapon, string source)
	{
		//IL_0030: 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)
		if (!IsMeleeWeapon(weapon))
		{
			return;
		}
		Animator animator = GetAnimator(weapon);
		if ((Object)(object)animator == (Object)null)
		{
			return;
		}
		AnimatorStateInfo currentAnimatorStateInfo = animator.GetCurrentAnimatorStateInfo(0);
		string currentClipName = GetCurrentClipName(animator);
		if (!IsSafeMeleeDrawClip(currentClipName))
		{
			return;
		}
		SafeAnimatorState value = SafeAnimatorStates.GetValue(weapon, (object _) => new SafeAnimatorState());
		value.FullPathHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash;
		value.ShortNameHash = ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).shortNameHash;
		value.ClipName = currentClipName;
		value.Valid = true;
		if (LogStateChanges.Value)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)("Cached safe melee animator state from " + source + ": clip=" + currentClipName + " fullPathHash=" + ((AnimatorStateInfo)(ref currentAnimatorStateInfo)).fullPathHash));
			}
		}
	}

	private static bool IsSafeMeleeDrawClip(string clipName)
	{
		if (string.IsNullOrEmpty(clipName))
		{
			return false;
		}
		if (ContainsIgnoreCase(clipName, "Slash"))
		{
			return false;
		}
		if (ContainsIgnoreCase(clipName, "Attack"))
		{
			return false;
		}
		if (ContainsIgnoreCase(clipName, "Fire"))
		{
			return false;
		}
		if (ContainsIgnoreCase(clipName, "ADS"))
		{
			return false;
		}
		if (ContainsIgnoreCase(clipName, "ToADS"))
		{
			return false;
		}
		if (ContainsIgnoreCase(clipName, "Charge") || ContainsIgnoreCase(clipName, "Charged"))
		{
			return false;
		}
		return ContainsIgnoreCase(clipName, "Equip");
	}

	private static bool ContainsIgnoreCase(string value, string part)
	{
		return value != null && part != null && value.IndexOf(part, StringComparison.OrdinalIgnoreCase) >= 0;
	}

	private static void PrepareMeleeAnimatorForFutureDraw(object weapon)
	{
		if (!ResetMeleeAnimatorBeforeSheathe.Value || !IsMeleeWeapon(weapon))
		{
			return;
		}
		try
		{
			InvokeSetAlternativeState(weapon, 0);
			if (fCurrentParries != null)
			{
				fCurrentParries.SetValue(weapon, 0);
			}
			Animator animator = GetAnimator(weapon);
			if ((Object)(object)animator == (Object)null)
			{
				return;
			}
			animator.SetBool("Charge", false);
			animator.SetBool("Sprinting", false);
			animator.SetBool("AlternativePressed", false);
			animator.ResetTrigger("Parry");
			if (!SafeAnimatorStates.TryGetValue(weapon, out var value) || value == null || !value.Valid)
			{
				CacheSafeMeleeAnimatorStateIfUseful(weapon, "PrepareMeleeAnimatorForFutureDraw fallback");
				if (!SafeAnimatorStates.TryGetValue(weapon, out value) || value == null || !value.Valid)
				{
					if (LogStateChanges.Value)
					{
						ManualLogSource log = Log;
						if (log != null)
						{
							log.LogInfo((object)("No cached safe melee animator state available for " + weapon));
						}
					}
					return;
				}
			}
			animator.Play(value.FullPathHash, 0, 0f);
			animator.Update(0f);
			if (LogStateChanges.Value)
			{
				ManualLogSource log2 = Log;
				if (log2 != null)
				{
					log2.LogInfo((object)("Reset melee animator to safe draw state before sheathe: " + value.ClipName + " hash=" + value.FullPathHash));
				}
			}
		}
		catch (Exception ex)
		{
			ManualLogSource log3 = Log;
			if (log3 != null)
			{
				log3.LogError((object)("Failed to prepare melee animator for future draw: " + ex));
			}
		}
	}

	private static void CleanCurrentMeleeWeaponState(object currentHoldable)
	{
		if (!IsMeleeWeapon(currentHoldable))
		{
			return;
		}
		try
		{
			PrepareMeleeAnimatorForFutureDraw(currentHoldable);
		}
		catch (Exception ex)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)("Failed to clean melee weapon state: " + ex));
			}
		}
	}

	private static string GetCurrentClipName(Animator animator)
	{
		if ((Object)(object)animator == (Object)null)
		{
			return string.Empty;
		}
		try
		{
			AnimatorClipInfo[] currentAnimatorClipInfo = animator.GetCurrentAnimatorClipInfo(0);
			if (currentAnimatorClipInfo != null && currentAnimatorClipInfo.Length != 0 && (Object)(object)((AnimatorClipInfo)(ref currentAnimatorClipInfo[0])).clip != (Object)null)
			{
				return ((Object)((AnimatorClipInfo)(ref currentAnimatorClipInfo[0])).clip).name;
			}
		}
		catch
		{
			return string.Empty;
		}
		return string.Empty;
	}

	private static float ClampRetryInterval()
	{
		if (ReChargeRetryInterval == null)
		{
			return 0.08f;
		}
		float value = ReChargeRetryInterval.Value;
		if (float.IsNaN(value) || float.IsInfinity(value))
		{
			return 0.08f;
		}
		return Mathf.Clamp(value, 0.01f, 0.5f);
	}

	private static bool WasMeleePressedThisFrame(object equipmentManager)
	{
		InputAction inputAction = GetInputAction(fMeleeFireAction, equipmentManager);
		InputAction inputAction2 = GetInputAction(fMeleeFireActionAlternative, equipmentManager);
		return WasPerformedThisFrame(inputAction) || WasPerformedThisFrame(inputAction2);
	}

	private static bool IsMeleeHeld(object equipmentManager)
	{
		InputAction inputAction = GetInputAction(fMeleeFireAction, equipmentManager);
		InputAction inputAction2 = GetInputAction(fMeleeFireActionAlternative, equipmentManager);
		bool flag = inputAction != null && inputAction.IsPressed();
		bool flag2 = inputAction2 != null && inputAction2.IsPressed();
		return flag || flag2;
	}

	private static bool IsAltFirePressed(object equipmentManager)
	{
		InputAction inputAction = GetInputAction(fAltFireAction, equipmentManager);
		return inputAction != null && inputAction.IsPressed();
	}

	private static bool WasPerformedThisFrame(InputAction action)
	{
		return action != null && action.WasPerformedThisFrame();
	}

	private static InputAction GetInputAction(FieldInfo field, object instance)
	{
		if (field == null || instance == null)
		{
			return null;
		}
		object? value = field.GetValue(instance);
		return (InputAction)((value is InputAction) ? value : null);
	}

	private static object GetCurrentHoldable(object equipmentManager)
	{
		if (fCurrentHoldable == null || equipmentManager == null)
		{
			return null;
		}
		return fCurrentHoldable.GetValue(equipmentManager);
	}

	private static object GetEquipmentManagerFromWeapon(object weapon)
	{
		if (fEquipmentManager == null || weapon == null)
		{
			return null;
		}
		return fEquipmentManager.GetValue(weapon);
	}

	private static bool IsMeleeWeapon(object holdable)
	{
		if (holdable == null)
		{
			return false;
		}
		if (!weaponType.IsInstanceOfType(holdable))
		{
			return false;
		}
		object value = pIsMelee.GetValue(holdable, null);
		return value is bool && (bool)value;
	}

	private static bool IsMeleeCharging(object weapon)
	{
		if (weapon == null || mIsMeleeCharging == null)
		{
			return false;
		}
		object obj = mIsMeleeCharging.Invoke(weapon, null);
		return obj is bool && (bool)obj;
	}

	private static bool IsInMeleeCharge(object equipmentManager)
	{
		return GetBoolField(fIsInMeleeCharge, equipmentManager);
	}

	private static bool IsAimingInputHeld(object equipmentManager)
	{
		return GetBoolField(fAimingInputHeld, equipmentManager);
	}

	private static bool IsMeleeInputCoolingDown(object equipmentManager)
	{
		if (fMeleeInputCooldown == null || equipmentManager == null)
		{
			return false;
		}
		object value = fMeleeInputCooldown.GetValue(equipmentManager);
		if (!(value is float))
		{
			return false;
		}
		return Time.time < (float)value;
	}

	private static bool GetBoolField(FieldInfo field, object instance)
	{
		if (field == null || instance == null)
		{
			return false;
		}
		object value = field.GetValue(instance);
		return value is bool && (bool)value;
	}

	private static void SetMeleePressed(object equipmentManager, bool value)
	{
		SetBoolField(fMeleePressed, equipmentManager, value);
	}

	private static void SetAlternativeMeleePressed(object equipmentManager, bool value)
	{
		SetBoolField(fAlternativeMeleePressed, equipmentManager, value);
	}

	private static void SetBoolField(FieldInfo field, object instance, bool value)
	{
		if (!(field == null) && instance != null)
		{
			field.SetValue(instance, value);
		}
	}

	private static void UpdateCurrentMeleeAlternativeAnimator(object equipmentManager, bool altHeld)
	{
		object currentHoldable = GetCurrentHoldable(equipmentManager);
		if (IsMeleeWeapon(currentHoldable))
		{
			Animator animator = GetAnimator(currentHoldable);
			if (!((Object)(object)animator == (Object)null))
			{
				animator.SetBool("AlternativePressed", altHeld);
			}
		}
	}

	private static Animator GetAnimator(object holdable)
	{
		if (holdable == null || pAnimator == null)
		{
			return null;
		}
		object? value = pAnimator.GetValue(holdable, null);
		return (Animator)((value is Animator) ? value : null);
	}

	private static void InvokeChargeBasicMelee(object equipmentManager)
	{
		try
		{
			mChargeBasicMelee.Invoke(equipmentManager, null);
		}
		catch (Exception ex)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)("Failed to invoke ChargeBasicMelee: " + ex));
			}
		}
	}

	private static void InvokeUseBasicMelee(object equipmentManager)
	{
		try
		{
			mUseBasicMelee.Invoke(equipmentManager, null);
		}
		catch (Exception ex)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)("Failed to invoke UseBasicMelee: " + ex));
			}
		}
	}

	private static void InvokeOnMeleeDone(object equipmentManager)
	{
		try
		{
			mOnMeleeDone.Invoke(equipmentManager, null);
		}
		catch (Exception ex)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)("Failed to invoke OnMeleeDone: " + ex));
			}
		}
	}

	private static void InvokeSetAlternativeState(object weapon, int value)
	{
		if (weapon == null || mSetAlternativeState == null)
		{
			return;
		}
		try
		{
			mSetAlternativeState.Invoke(weapon, new object[1] { value });
		}
		catch (Exception ex)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)("Failed to invoke SetAlternativeState: " + ex));
			}
		}
	}
}