using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using Agents; using BepInEx; using BepInEx.Configuration; using BepInEx.Unity.IL2CPP; using GTFO.API; using GTFO.API.Utilities; using GameData; using HarmonyLib; using Il2CppInterop.Runtime.Injection; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using Player; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("SprintReloadCancel")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+03abdeaaa296c87fd848075276a3990b9961708e")] [assembly: AssemblyProduct("SprintReloadCancel")] [assembly: AssemblyTitle("SprintReloadCancel")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace SprintReloadCancel { internal static class Configuration { public static bool SprintCancelEnabled = true; public static bool AimCancelEnabled = false; public static bool ShootCancelEnabled = false; public static bool SwapBuffer = true; private static ConfigFile configFile; internal static void Init() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Expected O, but got Unknown configFile = new ConfigFile(Path.Combine(Paths.ConfigPath, "SprintReloadCancel.cfg"), true); BindAll(configFile); LiveEdit.CreateListener(Paths.ConfigPath, "SprintReloadCancel.cfg", false).FileChanged += new LiveEditEventHandler(OnFileChanged); } private static void OnFileChanged(LiveEditEventArgs _) { configFile.Reload(); SprintCancelEnabled = (bool)configFile["Base Settings", "Sprint to Reload Cancel"].BoxedValue; AimCancelEnabled = (bool)configFile["Base Settings", "Aim to Reload Cancel"].BoxedValue; ShootCancelEnabled = (bool)configFile["Base Settings", "Shoot to Reload Cancel"].BoxedValue; SwapBuffer = (bool)configFile["Base Settings", "Reload Cancel Swap Buffer"].BoxedValue; } private static void BindAll(ConfigFile config) { SprintCancelEnabled = config.Bind("Base Settings", "Sprint to Reload Cancel", SprintCancelEnabled, "Sprinting will cancel reloads.").Value; AimCancelEnabled = config.Bind("Base Settings", "Aim to Reload Cancel", AimCancelEnabled, "Aiming will cancel reloads.").Value; ShootCancelEnabled = config.Bind("Base Settings", "Shoot to Reload Cancel", ShootCancelEnabled, "Shooting will cancel reloads.").Value; SwapBuffer = config.Bind("Base Settings", "Reload Cancel Swap Buffer", SwapBuffer, "After a reload cancel, buffers swap inputs until the next possible time.\nThis can mitigate missed inputs when you attempt to swap weapons right after reload canceling.").Value; } } [BepInPlugin("Dinorush.SprintReloadCancel", "SprintReloadCancel", "1.3.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] internal sealed class EntryPoint : BasePlugin { public const string MODNAME = "SprintReloadCancel"; public override void Load() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) new Harmony("SprintReloadCancel").PatchAll(); Configuration.Init(); AssetAPI.OnStartupAssetsLoaded += delegate { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown ClassInjector.RegisterTypeInIl2Cpp(); GameObject val = new GameObject("SprintReloadCancel"); Object.DontDestroyOnLoad((Object)val); val.AddComponent(); }; ((BasePlugin)this).Log.LogMessage((object)"Loaded SprintReloadCancel"); } } public sealed class ReloadCancelHandler : MonoBehaviour { private enum CancelState { Reload, SwapBack, SwapBuffer } private PlayerAgent? _owner; private ItemEquippable? _item; private CancelState _currentState; private InventorySlot _swapSlot; private float _reloadEndTime; private bool _bufferPush; private float _bufferEndTime; private const float SwapTime = 0.2f; private static readonly Dictionary SwapActions = new Dictionary { { (InputAction)23, (InventorySlot)1 }, { (InputAction)24, (InventorySlot)2 }, { (InputAction)25, (InventorySlot)3 }, { (InputAction)26, (InventorySlot)10 }, { (InputAction)28, (InventorySlot)5 }, { (InputAction)29, (InventorySlot)11 }, { (InputAction)27, (InventorySlot)4 } }; public static ReloadCancelHandler Instance { get; private set; } = null; public ReloadCancelHandler(IntPtr ptr) : base(ptr) { } private void Awake() { Instance = this; ((Behaviour)this).enabled = false; } private void ClearState() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) _item = null; _owner = null; _currentState = CancelState.Reload; _swapSlot = (InventorySlot)0; _bufferPush = false; ((Behaviour)this).enabled = false; } public void OnReloadStart(ItemEquippable item, float reloadEndTime) { PlayerAgent owner = ((Item)item).Owner; if (!((Object)(object)owner == (Object)null) && ((Agent)owner).IsLocallyOwned) { _item = item; _owner = owner; _reloadEndTime = reloadEndTime; _currentState = CancelState.Reload; ((Behaviour)this).enabled = true; } } private void Update() { //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_owner == (Object)null || (Object)(object)_item == (Object)null) { ClearState(); return; } switch (_currentState) { case CancelState.Reload: if (!_item.IsReloading) { ClearState(); } else if (ShouldCancel()) { _swapSlot = ((PlayerInventoryBase)_owner.FPItemHolder.m_inventoryLocal).WieldedSlot; _owner.FPItemHolder.MeleeAttackShortcut(); _currentState = CancelState.SwapBack; } break; case CancelState.SwapBack: _owner.Sync.WantsToWieldSlot(_swapSlot, false); if (Configuration.SwapBuffer) { _currentState = CancelState.SwapBuffer; _bufferEndTime = Clock.Time + 0.2f; } else { ClearState(); } break; case CancelState.SwapBuffer: CheckSwapBuffer(); break; } } private bool ShouldCancel() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) eFocusState inputFilter = _owner.InputFilter; if (!Configuration.SprintCancelEnabled || !InputMapper.GetButtonDown.Invoke((InputAction)9, inputFilter) || !_owner.Locomotion.InputIsForwardEnoughForRun()) { if (_reloadEndTime - 0.2f > Clock.Time) { if (!Configuration.AimCancelEnabled || !InputMapper.GetButtonDown.Invoke((InputAction)7, inputFilter)) { if (Configuration.ShootCancelEnabled) { return InputMapper.GetButtonDown.Invoke((InputAction)8, inputFilter); } return false; } return true; } return false; } return true; } private void CheckSwapBuffer() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) eFocusState inputFilter = _owner.InputFilter; if (Clock.Time < _bufferEndTime) { foreach (KeyValuePair swapAction in SwapActions) { if (InputMapper.GetButtonDown.Invoke(swapAction.Key, inputFilter)) { _swapSlot = swapAction.Value; _bufferPush = false; } } if (InputMapper.GetButtonDown.Invoke((InputAction)12, inputFilter)) { _bufferPush = true; } return; } if ((int)((PlayerInventoryBase)_owner.FPItemHolder.m_inventoryLocal).WieldedSlot != 8) { if (_bufferPush) { _owner.FPItemHolder.MeleeAttackShortcut(); } else if ((int)_swapSlot != 0) { _owner.Sync.WantsToWieldSlot(_swapSlot, false); } } ClearState(); } } [HarmonyPatch] internal static class ReloadCancelPatches { [HarmonyPatch(typeof(ItemEquippable), "TryTriggerReloadAnimationSequence")] [HarmonyWrapSafe] [HarmonyPostfix] public static void TrackReloadTime(ItemEquippable __instance, bool __result) { if (!__result || (Object)(object)((Item)__instance).Owner == (Object)null || !((Agent)((Item)__instance).Owner).IsLocallyOwned) { return; } GearFrontPartDataBlock frontData = __instance.GearPartHolder.FrontData; List obj = ((((frontData == null) ? null : frontData.ReloadSequence?.Count).GetValueOrDefault() > 0) ? __instance.GearPartHolder.FrontData.ReloadSequence : __instance.GearPartHolder.StockData.ReloadSequence); float triggerTime = obj[obj.Count - 1].TriggerTime; float num = __instance.ReloadTime / triggerTime; float num2 = 0f; Enumerator enumerator = obj.GetEnumerator(); while (enumerator.MoveNext()) { WeaponAnimSequenceItem current = enumerator.Current; if (current.TriggerTime > num2) { num2 = current.TriggerTime; } } ReloadCancelHandler.Instance.OnReloadStart(__instance, Clock.Time + num2 * num); } } }