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 LetsRumble v0.1.3
LetsRumble.dll
Decompiled 4 months agousing System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Threading.Tasks; using BepInEx; using BepInEx.Configuration; 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("LetsRumble")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LetsRumble")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("1a75fc54-dfa5-454f-a258-8eb69e47fca1")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] namespace LetsRumble; [HarmonyPatch(typeof(Character), "ApplyDamage")] public static class PlayerRumble_DamagePatch { private static void Postfix(Character __instance, HitData hit) { Player val = (Player)(object)((__instance is Player) ? __instance : null); if (val != null) { float totalDamage = hit.GetTotalDamage(); if (!(totalDamage <= 0f)) { float num = Mathf.Clamp(totalDamage / 50f, 0.1f, 1f); int durationMs = Mathf.Clamp((int)(totalDamage * 20f), 60, 500); Rumbler.Pulse(num * Plugin.DamageRumbleMultiplier.Value, num * Plugin.DamageRumbleMultiplier.Value, durationMs); } } } } [HarmonyPatch(typeof(GameCamera), "AddShake")] public static class PlayerRumble_ScreenShakePatch { private static void Postfix(Vector3 point, float range, float strength, bool continous) { if (Plugin.EnableEnvironmentRumble.Value && !(strength < 0.15f)) { if (range < 3f && strength < 1f) { Rumbler.Pulse(0.08f, 0.08f, 50); return; } float num = Mathf.Clamp(strength * 0.25f, 0.1f, 0.6f); int durationMs = Mathf.Clamp((int)(strength * 80f), 60, 200); Rumbler.Pulse(num, num, durationMs); } } } [HarmonyPatch(typeof(Player), "UseStamina")] public static class PlayerRumble_StaminaPatch { private static float _nextStepTime = 0f; private static bool _leftFoot = true; private static void Postfix(Player __instance, float v) { //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) if (__instance == null || !Plugin.EnableStaminaRumble.Value || v <= 0f || (Plugin.DisableSneakRumble.Value && ((Character)__instance).IsSneaking()) || (Plugin.DisableSwimmingRumble.Value && ((Character)__instance).IsSwimming()) || ((Character)__instance).InPlaceMode()) { return; } Vector3 velocity = ((Character)__instance).GetVelocity(); float magnitude = ((Vector3)(ref velocity)).magnitude; if (!(magnitude < 0.5f)) { if (((Character)__instance).IsRunning()) { HandleRunningRumble(__instance, v); } float maxStamina = ((Character)__instance).GetMaxStamina(); float stamina = __instance.GetStamina(); float num = Mathf.Clamp(v / maxStamina, 0.05f, 0.25f); int durationMs = Mathf.Clamp((int)(v * 6f), 30, 120); if (Plugin.EnableStaminaLightRumble.Value) { Rumbler.Pulse(num, num, durationMs); } if (stamina < maxStamina * 0.1f && Plugin.EnableStaminaCRITICALRumble.Value) { Rumbler.Pulse(0.5f * Plugin.StaminaRumbleMultiplier.Value, 0.5f * Plugin.StaminaRumbleMultiplier.Value, 250); } if (stamina <= 0f && Plugin.EnableStaminaCRITICALRumble.Value) { Rumbler.Pulse(1f * Plugin.StaminaRumbleMultiplier.Value, 1f * Plugin.StaminaRumbleMultiplier.Value, 500); } } } private static void HandleRunningRumble(Player __instance, float v) { if (((Character)__instance).IsRunning()) { float equipmentMovementModifier = ((Character)__instance).GetEquipmentMovementModifier(); float time = Time.time; float num = Mathf.Clamp(0.35f - equipmentMovementModifier * 0.02f, 0.15f, 0.35f); if (time >= _nextStepTime) { TriggerFootstepRumble(_leftFoot, __instance, v); _leftFoot = !_leftFoot; _nextStepTime = time + num; } } } private static void TriggerFootstepRumble(bool leftFoot, Player __instance, float v) { float maxStamina = ((Character)__instance).GetMaxStamina(); float stamina = __instance.GetStamina(); float num = Mathf.Clamp(v / maxStamina, 0.05f, 0.25f); float num2 = Mathf.Clamp(stamina / maxStamina / 3f, 0.15f, 0.45f); int durationMs = 10; if (leftFoot) { Rumbler.Pulse(num2, 0f, durationMs); } else { Rumbler.Pulse(0f, num2, durationMs); } } } [BepInPlugin("com.FunPlus.LetsRumble", "Lets Rumble", "0.1.3")] public class Plugin : BaseUnityPlugin { public static ConfigEntry<bool> EnableDamageRumble; public static ConfigEntry<bool> EnableStaminaRumble; public static ConfigEntry<bool> EnableStaminaLightRumble; public static ConfigEntry<bool> EnableStaminaHeavyRumble; public static ConfigEntry<bool> EnableStaminaCRITICALRumble; public static ConfigEntry<bool> DisableSneakRumble; public static ConfigEntry<bool> DisableSwimmingRumble; public static ConfigEntry<bool> EnableRunningRumble; public static ConfigEntry<float> RunningRumbleIntensity; public static ConfigEntry<float> DamageRumbleMultiplier; public static ConfigEntry<float> StaminaRumbleMultiplier; public static ConfigEntry<bool> EnableEnvironmentRumble; private Harmony _harmony; private void Awake() { //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Expected O, but got Unknown EnableDamageRumble = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableDamageRumble", true, "Trigger rumble when the player takes damage."); EnableStaminaRumble = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableStaminaRumble", true, "Trigger rumble when the player uses stamina."); EnableStaminaLightRumble = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableStaminaLightRumble", true, "Enable the rumble caused by Light stamina usage."); EnableStaminaHeavyRumble = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableStaminaHeavyRumble", true, "Enable the rumble caused by Heavy stamina usage."); EnableStaminaCRITICALRumble = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableStaminaCRITICALRumble", true, "Enable the rumble caused by depleting stamina."); DisableSneakRumble = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisableSneakRumble", true, "If true, stamina rumble will NOT trigger while sneaking."); DisableSwimmingRumble = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisableSwimmingRumble", true, "If true, stamina rumble will NOT trigger while swimming."); EnableRunningRumble = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableRunningRumble", true, "Trigger rumble when the player is running."); DamageRumbleMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Intensity", "DamageRumbleMultiplier", 1f, "Scale the strength of rumble caused by damage received."); StaminaRumbleMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Intensity", "StaminaRumbleMultiplier", 1f, "Scale the strength of rumble caused by stamina usage."); RunningRumbleIntensity = ((BaseUnityPlugin)this).Config.Bind<float>("Intensity", "RunningRumbleIntensity", 0.25f, "Base strength of running rumble (0.0–1.0)."); EnableEnvironmentRumble = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "EnableEnvironmentRumble", true, "Triggers rumble to environment situations; explosions, heavy stomps, etc."); _harmony = new Harmony("com.FunPlus.LetsRumble"); _harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"LetsRumble initialized with configurable settings!"); } } public static class Rumbler { private struct XInputVibration { public ushort wLeftMotorSpeed; public ushort wRightMotorSpeed; } [DllImport("XInput1_4.dll")] private static extern int XInputSetState(int dwUserIndex, ref XInputVibration pVibration); public static void Pulse(float strengthL, float strengthR, int durationMs) { try { ushort wLeftMotorSpeed = (ushort)(Mathf.Clamp01(strengthL) * 65535f); ushort wRightMotorSpeed = (ushort)(Mathf.Clamp01(strengthR) * 65535f); XInputVibration xInputVibration = default(XInputVibration); xInputVibration.wLeftMotorSpeed = wLeftMotorSpeed; xInputVibration.wRightMotorSpeed = wRightMotorSpeed; XInputVibration pVibration = xInputVibration; XInputSetState(0, ref pVibration); Timer(durationMs, Stop); } catch (Exception ex) { Debug.Log((object)("[LetsRumble] XInput error: " + ex.Message)); } } public static void Stop() { XInputVibration pVibration = default(XInputVibration); XInputSetState(0, ref pVibration); } private static async void Timer(int ms, Action callback) { await Task.Delay(ms); callback?.Invoke(); } }