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 EnableMod; internal static ConfigEntry FirePerformsMeleeAttack; internal static ConfigEntry ResetMeleeAnimatorBeforeSheathe; internal static ConfigEntry DisableWhenMeleeExpansionDetected; internal static ConfigEntry ReChargeRetryInterval; internal static ConfigEntry 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 States = new ConditionalWeakTable(); private static readonly ConditionalWeakTable SafeAnimatorStates = new ConditionalWeakTable(); 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("General", "EnableMod", true, "Enable Toggle Melee Stance."); FirePerformsMeleeAttack = ((BaseUnityPlugin)this).Config.Bind("Melee", "FirePerformsMeleeAttack", true, "When melee stance is toggled on, pressing the normal Fire action performs one melee attack."); ReChargeRetryInterval = ((BaseUnityPlugin)this).Config.Bind("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(0.01f, 0.5f), Array.Empty())); ResetMeleeAnimatorBeforeSheathe = ((BaseUnityPlugin)this).Config.Bind("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("Compatibility", "DisableWhenMeleeExpansionDetected", true, "Disable this standalone mod when kumo.sulfur.melee_expansion is installed."); LogStateChanges = ((BaseUnityPlugin)this).Config.Bind("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, "k__BackingField", "isInMeleeCharge"); fMeleePressed = FindFieldRecursive(equipmentManagerType, "k__BackingField", "meleePressed"); fAlternativeMeleePressed = FindFieldRecursive(equipmentManagerType, "k__BackingField", "alternativeMeleePressed"); fAimingInputHeld = FindFieldRecursive(equipmentManagerType, "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)); } } } }