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));
}
}
}
}