Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of BetterShotgun v1.4.7
BepInEx/plugins/BetterShotgun.dll
Decompiled 2 years agousing 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 { } }