Decompiled source of BetterShotgun v1.4.7

BepInEx/plugins/BetterShotgun.dll

Decompiled 8 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CSync.Lib;
using CSync.Util;
using GameNetcodeStuff;
using HarmonyLib;
using Hypick.BetterShotgun.NetcodePatcher;
using LethalCompanyInputUtils.Api;
using LethalLib.Modules;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: IgnoresAccessChecksTo("")]
[assembly: AssemblyCompany("Hypick.BetterShotgun")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.4.7.0")]
[assembly: AssemblyInformationalVersion("1.4.7+9fea18e15cb30613a2f100a51897cd4ce121054f")]
[assembly: AssemblyProduct("BetterShotgun")]
[assembly: AssemblyTitle("Hypick.BetterShotgun")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Hypick
{
	[BepInPlugin("Hypick.BetterShotgun", "BetterShotgun", "1.4.7")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		public static SyncConfig SyncConfig;

		private readonly Harmony _patcher = new Harmony("Hypick.BetterShotgun");

		public static readonly Keybinds InputActionsInstance = new Keybinds();

		private bool _isLoaded;

		private static Plugin Instance { get; set; }

		public static ManualLogSource Log => ((BaseUnityPlugin)Instance).Logger;

		private static IEnumerable<Item> AllItems => Resources.FindObjectsOfTypeAll<Item>().ToList();

		private static Item Shotgun => AllItems.FirstOrDefault((Func<Item, bool>)((Item item) => ((Object)item).name == "Shotgun"));

		private static Item ShotgunShell => AllItems.FirstOrDefault((Func<Item, bool>)((Item item) => ((Object)item).name == "GunAmmo"));

		public Plugin()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			Instance = this;
		}

		private void Awake()
		{
			SyncConfig = new SyncConfig(((BaseUnityPlugin)this).Config);
			SceneManager.sceneLoaded += OnSceneLoaded;
			_patcher.PatchAll();
			Log.LogInfo((object)"Patches applied");
			SetupKeybindCallbacks();
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Hypick.BetterShotgun is fully loaded!");
		}

		public void SetupKeybindCallbacks()
		{
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				if (SyncedInstance<SyncConfig>.Default.ReloadKeybind.Value.ToLower() != "e")
				{
					InputActionSetupExtensions.AddBinding(InputActionsInstance.ReloadKey, "<keyboard>/" + SyncedInstance<SyncConfig>.Default.ReloadKeybind.Value, (string)null, (string)null, (string)null);
					InputActionsInstance.ReloadKey.performed += OnReloadKeyPressed;
					Log.LogInfo((object)("ReloadKeybind is started using the " + InputActionRebindingExtensions.GetBindingDisplayString(InputActionsInstance.ReloadKey, (DisplayStringOptions)0, (string)null) + " key"));
				}
			}
			catch (Exception ex)
			{
				Log.LogError((object)"An error occurred while binding ReloadKeybind");
				Log.LogError((object)ex);
			}
		}

		public void OnReloadKeyPressed(CallbackContext context)
		{
			if (!((CallbackContext)(ref context)).performed || (Object)(object)GameNetworkManager.Instance == (Object)null || (Object)(object)GameNetworkManager.Instance.localPlayerController == (Object)null)
			{
				return;
			}
			PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController;
			if (!((NetworkBehaviour)localPlayerController).IsOwner)
			{
				return;
			}
			GrabbableObject val = localPlayerController.ItemSlots[localPlayerController.currentItemSlot];
			if ((Object)(object)val != (Object)null)
			{
				ShotgunItem val2 = (ShotgunItem)(object)((val is ShotgunItem) ? val : null);
				if (val2 != null && !val2.isReloading)
				{
					Utils.CheckInfiniteAmmo(val2);
					val2.StartReloadGun();
				}
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (!_isLoaded && ((Scene)(ref scene)).name == "MainMenu")
			{
				_isLoaded = true;
				Utils.RegisterItem(Shotgun, "Shotgun", SyncedInstance<SyncConfig>.Instance.ShotgunMaxDiscount.Value, SyncedInstance<SyncConfig>.Instance.ShotgunMinValue.Value, SyncedInstance<SyncConfig>.Instance.ShotgunMaxValue.Value, SyncedInstance<SyncConfig>.Instance.ShotgunWeight.Value, SyncedInstance<SyncConfig>.Instance.ShotgunPrice.Value, SyncedInstance<SyncConfig>.Instance.ShotgunRarity.Value);
				Utils.RegisterItem(ShotgunShell, "Shells", SyncedInstance<SyncConfig>.Instance.ShellMaxDiscount.Value, SyncedInstance<SyncConfig>.Instance.ShellMinValue.Value, SyncedInstance<SyncConfig>.Instance.ShellMaxValue.Value, 0f, SyncedInstance<SyncConfig>.Instance.ShellPrice.Value, SyncedInstance<SyncConfig>.Instance.ShellRarity.Value);
			}
		}
	}
	public static class Category
	{
		public const string Shotgun = "1 >> Shotgun << 1";

		public const string ShotgunTweaks = "3 >> Shotgun Tweaks << 3";

		public const string Shell = "2 >> Shell << 2";
	}
	[DataContract]
	public class SyncConfig : SyncedConfig<SyncConfig>
	{
		[DataMember]
		public SyncedEntry<int> ShotgunPrice { get; private set; }

		[DataMember]
		public SyncedEntry<int> ShotgunMaxDiscount { get; private set; }

		[DataMember]
		public SyncedEntry<int> ShotgunMinValue { get; private set; }

		[DataMember]
		public SyncedEntry<int> ShotgunMaxValue { get; private set; }

		[DataMember]
		public SyncedEntry<float> ShotgunWeight { get; private set; }

		[DataMember]
		public SyncedEntry<int> ShotgunRarity { get; private set; }

		[DataMember]
		public SyncedEntry<bool> MisfireOff { get; private set; }

		[DataMember]
		public SyncedEntry<bool> InfiniteAmmo { get; private set; }

		[DataMember]
		public SyncedEntry<string> ReloadKeybind { get; private set; }

		[DataMember]
		public SyncedEntry<bool> ShowAmmoCount { get; private set; }

		[DataMember]
		public SyncedEntry<bool> AmmoCheckAnimation { get; private set; }

		[DataMember]
		public SyncedEntry<bool> ReloadNoLimit { get; private set; }

		[DataMember]
		public SyncedEntry<bool> DisableFriendlyFire { get; private set; }

		[DataMember]
		public SyncedEntry<bool> SkipReloadAnimation { get; private set; }

		[DataMember]
		public SyncedEntry<int> ShellPrice { get; private set; }

		[DataMember]
		public SyncedEntry<int> ShellMaxDiscount { get; private set; }

		[DataMember]
		public SyncedEntry<int> ShellMinValue { get; private set; }

		[DataMember]
		public SyncedEntry<int> ShellMaxValue { get; private set; }

		[DataMember]
		public SyncedEntry<int> ShellRarity { get; private set; }

		public SyncConfig(ConfigFile cfg)
			: base("Hypick.BetterShotgun")
		{
			//IL_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Expected O, but got Unknown
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Expected O, but got Unknown
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_022c: Expected O, but got Unknown
			ConfigManager.Register<SyncConfig>(this);
			ShotgunPrice = Extensions.BindSyncedEntry<int>(cfg, "1 >> Shotgun << 1", "Price", 700, "Cost of a shotgun in a store. (-1 = remove from sale)");
			ShotgunMaxDiscount = Extensions.BindSyncedEntry<int>(cfg, "1 >> Shotgun << 1", "MaxDiscount", 80, new ConfigDescription("Maximum discount percentage in store (vanilla = 80)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 90), Array.Empty<object>()));
			ShotgunMinValue = Extensions.BindSyncedEntry<int>(cfg, "1 >> Shotgun << 1", "MinValueScrap", 40, "Minimum scrap cost (must be >= 0) (In the game, the value is scaled down, so it is calculated using the formula value * 100 / 40)");
			ShotgunMaxValue = Extensions.BindSyncedEntry<int>(cfg, "1 >> Shotgun << 1", "MaxValueScrap", 70, "Maximum scrap cost (must be >= min value) (In the game, the value is scaled down, so it is calculated using the formula value * 100 / 40)");
			ShotgunWeight = Extensions.BindSyncedEntry<float>(cfg, "1 >> Shotgun << 1", "Weight", 16f, new ConfigDescription("[BETA] Scrap weight", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 100f), Array.Empty<object>()));
			ShotgunRarity = Extensions.BindSyncedEntry<int>(cfg, "1 >> Shotgun << 1", "Rarity", -1, "Rarity of shotgun spawn on moons (higher = more common). A shotgun will also appear in gifts. (-1 = disable)");
			MisfireOff = Extensions.BindSyncedEntry<bool>(cfg, "3 >> Shotgun Tweaks << 3", "MisfireOff", true, "If set to true, it disables the shotgun misfire (vanilla = false)");
			InfiniteAmmo = Extensions.BindSyncedEntry<bool>(cfg, "3 >> Shotgun Tweaks << 3", "InfiniteAmmo", false, "If set to true, there will be endless rounds in the shotgun");
			ReloadKeybind = Extensions.BindSyncedEntry<string>(cfg, "3 >> Shotgun Tweaks << 3", "ReloadKeybind", "R", "Changes the reload key to the one you specify (vanilla = E)");
			ShowAmmoCount = Extensions.BindSyncedEntry<bool>(cfg, "3 >> Shotgun Tweaks << 3", "ShowAmmoCount", true, "If set to true, the number of loaded cartridges will be displayed in the tooltip");
			AmmoCheckAnimation = Extensions.BindSyncedEntry<bool>(cfg, "3 >> Shotgun Tweaks << 3", "AmmoCheckAnimation", false, "[BETA] Enables animation of checking cartridges in a shotgun by pressing the reload key (Does not work when InfiniteAmmo = true)");
			ReloadNoLimit = Extensions.BindSyncedEntry<bool>(cfg, "3 >> Shotgun Tweaks << 3", "ReloadNoLimit", false, "If set to true, there will be no restrictions on the number of rounds in the shotgun");
			DisableFriendlyFire = Extensions.BindSyncedEntry<bool>(cfg, "3 >> Shotgun Tweaks << 3", "DisableFriendlyFire", false, "Turns off friendly fire");
			SkipReloadAnimation = Extensions.BindSyncedEntry<bool>(cfg, "3 >> Shotgun Tweaks << 3", "SkipReloadAnimation", false, "Skips the shotgun reload animation");
			ShellPrice = Extensions.BindSyncedEntry<int>(cfg, "2 >> Shell << 2", "Price", 50, "Cost of a shotgun shell in a store. (-1 = remove from sale)");
			ShellMaxDiscount = Extensions.BindSyncedEntry<int>(cfg, "2 >> Shell << 2", "MaxDiscount", 80, new ConfigDescription("Maximum discount percentage in store (vanilla = 80)", (AcceptableValueBase)(object)new AcceptableValueRange<int>(0, 90), Array.Empty<object>()));
			ShellMinValue = Extensions.BindSyncedEntry<int>(cfg, "2 >> Shell << 2", "MinValueScrap", 15, "Minimum scrap cost (must be >= 0) (In the game, the value is scaled down, so it is calculated using the formula value * 100 / 40)");
			ShellMaxValue = Extensions.BindSyncedEntry<int>(cfg, "2 >> Shell << 2", "MaxValueScrap", 25, "Maximum scrap cost (must be >= min value) (In the game, the value is scaled down, so it is calculated using the formula value * 100 / 40)");
			ShellRarity = Extensions.BindSyncedEntry<int>(cfg, "2 >> Shell << 2", "Rarity", 2, "Rarity of shotgun shell spawns on moons (higher = more common). Shell will also appear in gifts. (-1 = disable)");
		}
	}
	public class Keybinds : LcInputActions
	{
		public InputAction ReloadKey => ((LcInputActions)this).Asset["Reload"];

		public override void CreateInputActions(in InputActionMapBuilder builder)
		{
			builder.NewActionBinding().WithActionId("Reload").WithActionType((InputActionType)1)
				.WithBindingName("ReloadShotgunKey")
				.Finish();
		}
	}
	public class Utils
	{
		public static void CheckInfiniteAmmo(ShotgunItem __instance)
		{
			if (SyncedInstance<SyncConfig>.Instance.InfiniteAmmo.Value)
			{
				__instance.shellsLoaded = 3;
			}
		}

		public static bool CheckFriendly(ShotgunItem __instance)
		{
			return (Object)(object)((GrabbableObject)__instance).playerHeldBy != (Object)null;
		}

		public static string GetCustomTooltip(ShotgunItem __instance)
		{
			string text = (SyncedInstance<SyncConfig>.Default.AmmoCheckAnimation.Value ? "Reload / Check" : "Reload");
			if (!SyncedInstance<SyncConfig>.Default.ShowAmmoCount.Value)
			{
				return text + ": [" + InputActionRebindingExtensions.GetBindingDisplayString(Plugin.InputActionsInstance.ReloadKey, (DisplayStringOptions)0, (string)null) + "]";
			}
			string arg = (SyncedInstance<SyncConfig>.Instance.ReloadNoLimit.Value ? "∞" : "2");
			string text2 = (SyncedInstance<SyncConfig>.Instance.InfiniteAmmo.Value ? "∞" : $"{__instance.shellsLoaded}/{arg}");
			return text + " (" + text2 + "): [" + InputActionRebindingExtensions.GetBindingDisplayString(Plugin.InputActionsInstance.ReloadKey, (DisplayStringOptions)0, (string)null) + "]";
		}

		public static void RegisterItem(Item item, string name, int maxDiscount, int minValue, int maxValue, float weight, int price, int rarity)
		{
			item.itemName = name;
			item.highestSalePercentage = maxDiscount;
			item.minValue = Mathf.Max(minValue, 0) * 100 / 40;
			item.maxValue = Mathf.Max(maxValue, item.minValue) * 100 / 40;
			item.weight = ((weight <= 9f) ? ((weight + 100f) / 100f) : ((weight + 99f) / 100f));
			if (price != -1)
			{
				Items.RegisterShopItem(item, price);
				Plugin.Log.LogInfo((object)(item.itemName + " added to the store"));
			}
			if (rarity != -1)
			{
				Items.RegisterScrap(item, rarity, (LevelTypes)(-1));
				Plugin.Log.LogInfo((object)(item.itemName + " added as scrap"));
			}
			Plugin.Log.LogInfo((object)("Loaded " + item.itemName));
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "Hypick.BetterShotgun";

		public const string PLUGIN_NAME = "BetterShotgun";

		public const string PLUGIN_VERSION = "1.4.7";
	}
}
namespace Hypick.Patches
{
	[HarmonyPatch(typeof(ShotgunItem))]
	internal class ShotgunItemPatch
	{
		[HarmonyPatch("Update")]
		[HarmonyPrefix]
		public static void Update(ShotgunItem __instance)
		{
			if (SyncedInstance<SyncConfig>.Instance.MisfireOff.Value && !__instance.safetyOn)
			{
				__instance.hasHitGroundWithSafetyOff = true;
				__instance.misfireTimer = float.MaxValue;
			}
		}

		[HarmonyPatch("ItemActivate")]
		[HarmonyPrefix]
		public static void ItemActivate(ShotgunItem __instance)
		{
			Utils.CheckInfiniteAmmo(__instance);
		}

		[HarmonyPatch("SetControlTipsForItem")]
		[HarmonyPrefix]
		public static void SetControlTipsForItem(ShotgunItem __instance)
		{
			((GrabbableObject)__instance).itemProperties.toolTips[1] = Utils.GetCustomTooltip(__instance);
		}

		[HarmonyPatch("SetSafetyControlTip")]
		[HarmonyPrefix]
		public static void SetSafetyControlTip(ShotgunItem __instance)
		{
			if (((NetworkBehaviour)__instance).IsOwner)
			{
				HUDManager.Instance.ChangeControlTip(2, Utils.GetCustomTooltip(__instance), false);
			}
		}

		[HarmonyPatch("ReloadGunEffectsClientRpc")]
		[HarmonyPatch("ShootGun")]
		[HarmonyPostfix]
		public static void UpdateControlTipsForItem(ShotgunItem __instance)
		{
			if (SyncedInstance<SyncConfig>.Default.ShowAmmoCount.Value)
			{
				__instance.SetSafetyControlTip();
			}
		}

		[HarmonyPatch("ShootGun")]
		[HarmonyPrefix]
		[HarmonyPriority(600)]
		public static void ShootGunPrefix(ShotgunItem __instance, out int __state)
		{
			__state = __instance.shellsLoaded;
		}

		[HarmonyPatch("ShootGun")]
		[HarmonyPostfix]
		public static void ShootGunPostfix(ShotgunItem __instance, ref int __state)
		{
			__instance.shellsLoaded = Mathf.Max(0, __state - 1);
			__instance.SetSafetyControlTip();
		}

		[HarmonyPatch("reloadGunAnimation")]
		[HarmonyPrefix]
		public static bool ReloadGunAnimation(ShotgunItem __instance, ref IEnumerator __result)
		{
			__result = ReloadGunAnimationCustom(__instance);
			return false;
		}

		[HarmonyPatch("ShootGun")]
		public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			bool found = false;
			foreach (CodeInstruction instruction in instructions)
			{
				if (SyncedInstance<SyncConfig>.Instance.DisableFriendlyFire.Value && !found && ((object)instruction).ToString().Contains("playerHeldBy"))
				{
					found = true;
					yield return new CodeInstruction(OpCodes.Ldarg_0, (object)null);
					yield return new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(ShotgunItemPatch), "CheckFriendly", (Type[])null, (Type[])null));
					yield return new CodeInstruction(OpCodes.Stloc_0, (object)null);
				}
				yield return instruction;
			}
		}

		[HarmonyPatch("ItemInteractLeftRight")]
		[HarmonyPrefix]
		public static bool ItemInteractLeftRight(ShotgunItem __instance, bool right)
		{
			if (SyncedInstance<SyncConfig>.Default.ReloadKeybind.Value.ToLower() != "e" && right)
			{
				return false;
			}
			if (SyncedInstance<SyncConfig>.Instance.ReloadNoLimit.Value && right && !__instance.isReloading)
			{
				__instance.StartReloadGun();
				return false;
			}
			return true;
		}

		[HarmonyPatch("StartReloadGun")]
		[HarmonyPrefix]
		public static bool StartReloadGun(ShotgunItem __instance)
		{
			if ((SyncedInstance<SyncConfig>.Default.AmmoCheckAnimation.Value && !__instance.ReloadedGun()) || (SyncedInstance<SyncConfig>.Default.AmmoCheckAnimation.Value && !SyncedInstance<SyncConfig>.Instance.ReloadNoLimit.Value && !SyncedInstance<SyncConfig>.Instance.InfiniteAmmo.Value && __instance.shellsLoaded >= 2))
			{
				if (__instance.gunCoroutine != null)
				{
					((MonoBehaviour)__instance).StopCoroutine(__instance.gunCoroutine);
				}
				__instance.gunCoroutine = ((MonoBehaviour)__instance).StartCoroutine(CheckAmmoAnimation(__instance));
				return false;
			}
			if (SyncedInstance<SyncConfig>.Instance.InfiniteAmmo.Value && __instance.ReloadedGun())
			{
				return false;
			}
			return ((NetworkBehaviour)__instance).IsOwner;
		}

		[HarmonyPatch("StopUsingGun")]
		[HarmonyPrefix]
		public static bool StopUsingGunPrefix(ShotgunItem __instance)
		{
			PlayerControllerB val = ((GrabbableObject)__instance).playerHeldBy ?? __instance.previousPlayerHeldBy;
			if (SyncedInstance<SyncConfig>.Default.AmmoCheckAnimation.Value && (Object)(object)val != (Object)null)
			{
				val.playerBodyAnimator.speed = 1f;
				__instance.gunAudio.time = 0f;
			}
			return true;
		}

		private static IEnumerator CheckAmmoAnimation(ShotgunItem __instance)
		{
			__instance.isReloading = true;
			((GrabbableObject)__instance).playerHeldBy.playerBodyAnimator.SetBool("ReloadShotgun", true);
			((Renderer)__instance.shotgunShellLeft).enabled = __instance.shellsLoaded > 0;
			((Renderer)__instance.shotgunShellRight).enabled = __instance.shellsLoaded > 1;
			yield return (object)new WaitForSeconds(0.3f);
			__instance.gunAudio.clip = __instance.gunReloadSFX;
			__instance.gunAudio.Play();
			__instance.gunAnimator.SetBool("Reloading", true);
			yield return (object)new WaitForSeconds(0.45f);
			__instance.gunAudio.Stop();
			((GrabbableObject)__instance).playerHeldBy.playerBodyAnimator.speed = 0.2f;
			__instance.gunAudio.time = 0.7f;
			__instance.gunAudio.Play();
			yield return (object)new WaitForSeconds(0.95f);
			((GrabbableObject)__instance).playerHeldBy.playerBodyAnimator.speed = 0.6f;
			((GrabbableObject)__instance).playerHeldBy.playerBodyAnimator.SetBool("ReloadShotgun", false);
			__instance.gunAnimator.SetBool("Reloading", false);
			yield return (object)new WaitForSeconds(0.3f);
			__instance.gunAudio.time = 0f;
			__instance.gunAudio.Stop();
			((GrabbableObject)__instance).playerHeldBy.playerBodyAnimator.speed = 1f;
			__instance.isReloading = false;
			__instance.ReloadGunEffectsServerRpc(false);
		}

		private static IEnumerator ReloadGunAnimationCustom(ShotgunItem __instance)
		{
			if (!SyncedInstance<SyncConfig>.Instance.SkipReloadAnimation.Value)
			{
				__instance.isReloading = true;
				if (__instance.shellsLoaded <= 0)
				{
					((GrabbableObject)__instance).playerHeldBy.playerBodyAnimator.SetBool("ReloadShotgun", true);
					((Renderer)__instance.shotgunShellLeft).enabled = false;
					((Renderer)__instance.shotgunShellRight).enabled = false;
				}
				else
				{
					((GrabbableObject)__instance).playerHeldBy.playerBodyAnimator.SetBool("ReloadShotgun2", true);
					((Renderer)__instance.shotgunShellRight).enabled = false;
				}
				yield return (object)new WaitForSeconds(0.3f);
				__instance.gunAudio.PlayOneShot(__instance.gunReloadSFX);
				__instance.gunAnimator.SetBool("Reloading", true);
				__instance.ReloadGunEffectsServerRpc(true);
				yield return (object)new WaitForSeconds(0.95f);
				((Renderer)__instance.shotgunShellInHand).enabled = true;
				__instance.shotgunShellInHandTransform.SetParent(((GrabbableObject)__instance).playerHeldBy.leftHandItemTarget);
				__instance.shotgunShellInHandTransform.localPosition = new Vector3(-0.0555f, 0.1469f, -0.0655f);
				__instance.shotgunShellInHandTransform.localEulerAngles = new Vector3(-1.956f, 143.856f, -16.427f);
				yield return (object)new WaitForSeconds(0.95f);
				((GrabbableObject)__instance).playerHeldBy.DestroyItemInSlotAndSync(__instance.ammoSlotToUse);
				__instance.ammoSlotToUse = -1;
				if (SyncedInstance<SyncConfig>.Instance.ReloadNoLimit.Value)
				{
					__instance.shellsLoaded++;
				}
				else
				{
					__instance.shellsLoaded = Mathf.Clamp(__instance.shellsLoaded + 1, 0, 2);
				}
				((Renderer)__instance.shotgunShellLeft).enabled = true;
				if (__instance.shellsLoaded >= 2)
				{
					((Renderer)__instance.shotgunShellRight).enabled = true;
				}
				((Renderer)__instance.shotgunShellInHand).enabled = false;
				__instance.shotgunShellInHandTransform.SetParent(((Component)__instance).transform);
				yield return (object)new WaitForSeconds(0.45f);
				__instance.gunAudio.PlayOneShot(__instance.gunReloadFinishSFX);
				__instance.gunAnimator.SetBool("Reloading", false);
				((GrabbableObject)__instance).playerHeldBy.playerBodyAnimator.SetBool("ReloadShotgun", false);
				((GrabbableObject)__instance).playerHeldBy.playerBodyAnimator.SetBool("ReloadShotgun2", false);
				__instance.isReloading = false;
				__instance.ReloadGunEffectsServerRpc(false);
			}
			else
			{
				Plugin.Log.LogInfo((object)"Skip reload animation");
				__instance.isReloading = true;
				((GrabbableObject)__instance).playerHeldBy.DestroyItemInSlotAndSync(__instance.ammoSlotToUse);
				__instance.ammoSlotToUse = -1;
				if (SyncedInstance<SyncConfig>.Instance.ReloadNoLimit.Value)
				{
					__instance.shellsLoaded++;
				}
				else
				{
					__instance.shellsLoaded = Mathf.Clamp(__instance.shellsLoaded + 1, 0, 2);
				}
				((Renderer)__instance.shotgunShellLeft).enabled = true;
				if (__instance.shellsLoaded >= 2)
				{
					((Renderer)__instance.shotgunShellRight).enabled = true;
				}
				((Renderer)__instance.shotgunShellInHand).enabled = false;
				__instance.shotgunShellInHandTransform.SetParent(((Component)__instance).transform);
				__instance.isReloading = false;
				__instance.SetSafetyControlTip();
			}
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}
namespace Hypick.BetterShotgun.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}