Please disclose if your mod was created primarily 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 Crossbow Reload Tweaked v1.1.1
CrossbowReloadTweak.dll
Decompiled 10 months agousing System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("CrossbowReloadTweak")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CrossbowReloadTweak")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("a3a9671a-936a-44f2-a674-710820bfddb2")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace CrossbowReloadTweak; [BepInPlugin("cr.crossbowreloadtweak", "Crossbow Reload Tweak", "1.1.1")] public class CrossbowReloadTweak : BaseUnityPlugin { [HarmonyPatch(typeof(Player), "UpdateActionQueue")] public class Player_UpdateActionQueue_Patch { private static bool Prefix(Player __instance) { if (__instance.m_actionQueue.Count == 0) { return true; } if (!IsPlayerReloading(__instance)) { return true; } bool flag = IsPlayerMoving(__instance); if (!flag && Instance.reloadStaminaStationaryEnabled.Value) { if (Instance.verboseLogging.Value) { logger.LogInfo((object)"UpdateActionQueue: Current action is a reload and player is not moving: Prefix"); } originalStaminaDrain[__instance] = __instance.m_actionQueue[0].m_staminaDrain; MinorActionData obj = __instance.m_actionQueue[0]; obj.m_staminaDrain *= Instance.reloadStaminaStationaryMod.Value; } else if (flag && Instance.reloadStaminaMovingEnabled.Value) { if (Instance.verboseLogging.Value) { logger.LogInfo((object)"UpdateActionQueue: Current action is a reload and player is moving: Prefix"); } originalStaminaDrain[__instance] = __instance.m_actionQueue[0].m_staminaDrain; MinorActionData obj2 = __instance.m_actionQueue[0]; obj2.m_staminaDrain *= Instance.reloadStaminaMovingMod.Value; } return true; } private static void Postfix(Player __instance, float dt) { if (__instance.m_actionQueue.Count == 0 || !IsPlayerReloading(__instance)) { return; } bool flag = IsPlayerMoving(__instance); if (flag && Instance.reloadSpeedMovingEnabled.Value) { MinorActionData obj = __instance.m_actionQueue[0]; obj.m_time += dt * Instance.reloadSpeedMovingMod.Value; if (Instance.verboseLogging.Value) { logger.LogInfo((object)"UpdateActionQueue: Current action is a reload and player is moving: Postfix"); logger.LogInfo((object)("UpdateActionQueue: Current reload speed modifier is : " + Instance.reloadSpeedMovingMod.Value)); } } else if (!flag && Instance.reloadSpeedStationaryEnabled.Value) { MinorActionData obj2 = __instance.m_actionQueue[0]; obj2.m_time += dt * Instance.reloadSpeedStationaryMod.Value; if (Instance.verboseLogging.Value) { logger.LogInfo((object)"UpdateActionQueue: Current action is a reload and player is not moving: Postfix"); logger.LogInfo((object)("UpdateActionQueue: Current reload speed modifier is : " + Instance.reloadSpeedStationaryMod.Value)); } } if (!((Character)__instance).HaveStamina(0f) && Instance.noStaminaReloadSpeedEnabled.Value) { MinorActionData obj3 = __instance.m_actionQueue[0]; obj3.m_time += dt * Instance.noStaminaReloadSpeedMod.Value; logger.LogInfo((object)"UpdateActionQueue: Current action is a reload and player has no stamina: Postfix"); logger.LogInfo((object)("UpdateActionQueue: Current reload speed modifier is : " + Instance.noStaminaReloadSpeedMod.Value)); } if (originalStaminaDrain.TryGetValue(__instance, out var value)) { __instance.m_actionQueue[0].m_staminaDrain = value; originalStaminaDrain.Remove(__instance); } } } [HarmonyPatch(typeof(Player), "GetJogSpeedFactor")] public class Player_GetJogSpeedFactor_Patch { private static void Postfix(Player __instance, ref float __result) { if (!IsPlayerReloading(__instance)) { return; } if (Instance.movementSpeedEnabled.Value) { __result *= Instance.movementSpeedModifier.Value; if (Instance.verboseLogging.Value) { logger.LogInfo((object)("GetJogSpeedFactor: Player is reloading, jog speed factor is: " + __result)); } } if (!((Character)__instance).HaveStamina(0f) && Instance.noStaminaMovementSpeedEnabled.Value) { __result *= Instance.noStaminaMovementSpeedMod.Value; if (Instance.verboseLogging.Value) { logger.LogInfo((object)("GetJogSpeedFactor: Player is reloading an has no stamina, jog speed factor is: " + __result)); } } } } private readonly Harmony HarmonyInstance = new Harmony("cr.crossbowreloadtweak"); private static ManualLogSource logger; private ConfigEntry<float> movementDetectionSpeed; private ConfigEntry<float> movementSpeedModifier; private ConfigEntry<bool> movementSpeedEnabled; private ConfigEntry<float> reloadSpeedStationaryMod; private ConfigEntry<bool> reloadSpeedStationaryEnabled; private ConfigEntry<float> reloadSpeedMovingMod; private ConfigEntry<bool> reloadSpeedMovingEnabled; private ConfigEntry<float> reloadStaminaMovingMod; private ConfigEntry<bool> reloadStaminaMovingEnabled; private ConfigEntry<float> reloadStaminaStationaryMod; private ConfigEntry<bool> reloadStaminaStationaryEnabled; private ConfigEntry<float> noStaminaMovementSpeedMod; private ConfigEntry<bool> noStaminaMovementSpeedEnabled; private ConfigEntry<float> noStaminaReloadSpeedMod; private ConfigEntry<bool> noStaminaReloadSpeedEnabled; private static Dictionary<Player, float> originalStaminaDrain = new Dictionary<Player, float>(); private ConfigEntry<bool> verboseLogging; public static CrossbowReloadTweak Instance { get; private set; } private void Awake() { Instance = this; logger = ((BaseUnityPlugin)this).Logger; movementDetectionSpeed = ((BaseUnityPlugin)this).Config.Bind<float>("Other", "Movement Detection Speed", 0.001f, "Only useful to change if you are using a controller. Any movement speed in movement direction biger than this value would be consider moving."); movementSpeedModifier = ((BaseUnityPlugin)this).Config.Bind<float>("Reload Movement Speed", "Modifier", 0.65f, "Movement speed modifier value. Affects jogging speed while reloading. 0 - 1 decereases movement speed. Anything above '1' is speed increase. Anything negative inverts movement direction"); movementSpeedEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Reload Movement Speed", "Enable", true, "Activates movement speed modifier"); reloadSpeedStationaryMod = ((BaseUnityPlugin)this).Config.Bind<float>("Stationary Reload Speed", "Modifier", 0.4f, "Reload speed modifier value while stationary. Affects reload animation clock while not moving. '0' no change, '1' double speed. Anything between '-1' to '0' is a decrease"); reloadSpeedStationaryEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Stationary Reload Speed", "Enable", true, "Activates stationary reload speed modifier"); reloadSpeedMovingMod = ((BaseUnityPlugin)this).Config.Bind<float>("Moving Reload Speed", "Modifier", -0.3f, "Reload speed modifier value while moving. Affects reload animation clock while moving. '0' no change, '1' double speed. Anything between '-1' to '0' is a decrease."); reloadSpeedMovingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Moving Reload Speed", "Enable", true, "Activates moving reload speed modifier."); reloadStaminaStationaryMod = ((BaseUnityPlugin)this).Config.Bind<float>("Stationary Reload Stamina Drain", "Modifier", 0f, "Multiplies vanilla stamina drain with this value while stationary. '0' no stamina drain, '1' same as vanilla, '2' double stamina drain."); reloadStaminaStationaryEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Stationary Reload Stamina Drain", "Enable", false, "Activates stationary stamina drain modifier."); reloadStaminaMovingMod = ((BaseUnityPlugin)this).Config.Bind<float>("Moving Reload Stamina Drain", "Modifier", 0f, "Multiplies vanilla stamina drain with this value while moving. '0' no stamina drain, '1' same as vanilla, '2' double stamina drain."); reloadStaminaMovingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Moving Reload Stamina Drain", "Enable", false, "Activates moving stamina drain modifier."); noStaminaMovementSpeedMod = ((BaseUnityPlugin)this).Config.Bind<float>("No Stamina Movement Speed", "Modifier", 0f, "Controls movement speed while out of stamina. Works same as *Reload Movement Speed*"); noStaminaMovementSpeedEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("No Stamina Movement Speed", "Enable", false, "Activates no stamina movement speed modifier"); noStaminaReloadSpeedMod = ((BaseUnityPlugin)this).Config.Bind<float>("No Stamina Reload Speed", "Modifier", 0f, "Controls reload speed while out of stamina. Works same as Stationary Reload Speed"); noStaminaReloadSpeedEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("No Stamina Reload Speed", "Enable", false, "Activates no stamina reload speed modifier"); verboseLogging = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "Enable Verbose Logging", false, "Enables verbose logging."); Assembly executingAssembly = Assembly.GetExecutingAssembly(); HarmonyInstance.PatchAll(executingAssembly); } public static bool IsPlayerReloading(Player player) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 if (player.m_actionQueue.Count == 0) { return false; } if ((int)player.m_actionQueue[0].m_type == 2) { return true; } return false; } public static bool IsPlayerMoving(Player player) { if ((Object)(object)player == (Object)null) { return false; } if (((Vector3)(ref ((Character)player).m_moveDir)).magnitude < Instance.movementDetectionSpeed.Value) { return false; } return true; } }