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