Decompiled source of SprintReloadCancel v1.3.4

SprintReloadCancel.dll

Decompiled 3 weeks ago
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<bool>("Base Settings", "Sprint to Reload Cancel", SprintCancelEnabled, "Sprinting will cancel reloads.").Value;
			AimCancelEnabled = config.Bind<bool>("Base Settings", "Aim to Reload Cancel", AimCancelEnabled, "Aiming will cancel reloads.").Value;
			ShootCancelEnabled = config.Bind<bool>("Base Settings", "Shoot to Reload Cancel", ShootCancelEnabled, "Shooting will cancel reloads.").Value;
			SwapBuffer = config.Bind<bool>("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<ReloadCancelHandler>();
				GameObject val = new GameObject("SprintReloadCancel");
				Object.DontDestroyOnLoad((Object)val);
				val.AddComponent<ReloadCancelHandler>();
			};
			((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<InputAction, InventorySlot> SwapActions = new Dictionary<InputAction, InventorySlot>
		{
			{
				(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<InputAction, InventorySlot> 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<WeaponAnimSequenceItem> 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<WeaponAnimSequenceItem> 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);
		}
	}
}