using UnityEngine;
using UnityEngine.InputSystem;
namespace ProjectM.Client
{
///
/// Gamepad rumble for combat feel — a static bridge (mirrors / ).
/// sets the motors and stamps a stop time; (called once per frame from
/// CombatFeedbackSystem) stops them when the pulse elapses OR the app loses focus, so a rumble never sticks.
/// A no-op when no pad is connected; the CALLER gates to the Gamepad scheme. Statics survive fast-enter-playmode
/// reloads, so re-arms clean on play-enter and stops any leaked motor (the AimPresentation
/// reset idiom). Presentation-only, main-thread, never touches the simulation.
///
public static class RumbleUtil
{
static float s_StopTime;
static bool s_Active;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
static void ResetState()
{
s_Active = false;
s_StopTime = 0f;
Stop();
}
/// Pulse both motors at the given low/high strengths for durSec, then auto-stop. No-op without a pad.
public static void Pulse(float low, float high, float durSec)
{
var pad = Gamepad.current;
if (pad == null) return;
pad.SetMotorSpeeds(Mathf.Clamp01(low), Mathf.Clamp01(high));
s_StopTime = Time.unscaledTime + Mathf.Max(0.02f, durSec);
s_Active = true;
}
/// Call once per frame: stops the motors when the pulse elapses or focus is lost.
public static void Tick()
{
if (!s_Active) return;
if (!Application.isFocused || Time.unscaledTime >= s_StopTime)
{
Stop();
s_Active = false;
}
}
static void Stop()
{
var pad = Gamepad.current;
if (pad != null) pad.ResetHaptics();
}
}
}