using UnityEngine;
using UnityEngine.InputSystem;
/// <summary>
/// GAME 1303 Tier 3 — Hold Sprint to run faster. Apep's Trial, Missile Man.
///
/// SETUP
/// - Add to the player (PlayerController2D v1.1). Uses the default "Sprint" action
/// (Left Shift / gamepad left stick press). Nothing else to wire.
/// - Toggle Mode: press once to start, again to stop (instead of hold).
/// - Optional stamina: set Stamina Seconds > 0 to limit sprinting; it refills when
/// not sprinting. OnStaminaChanged(0-1) feeds a HUD bar.
/// - Animator: PlayerAnimatorBridge's Speed float goes up naturally, so your
/// Walk -> Run transition threshold handles the animation.
/// </summary>
public class Sprint : MonoBehaviour
{
public float sprintMultiplier = 1.6f;
public bool toggleMode = false;
[Header("Stamina (0 = unlimited)")]
public float staminaSeconds = 0f;
public float refillRate = 1f; // seconds of stamina regained per second
public UnityEngine.Events.UnityEvent<float> OnStaminaChanged;
public bool IsSprinting { get; private set; }
public float Stamina { get; private set; }
private PlayerController2D controller;
private bool held;
void Awake()
{
controller = GetComponent<PlayerController2D>();
Stamina = staminaSeconds;
}
void OnSprint(InputValue v)
{
if (toggleMode) { if (v.isPressed) held = !held; }
else held = v.isPressed;
}
void Update()
{
bool moving = Mathf.Abs(controller.MoveInput) > 0.1f;
bool canSprint = held && moving && controller.InputEnabled && (staminaSeconds <= 0f || Stamina > 0f);
if (canSprint != IsSprinting)
{
IsSprinting = canSprint;
// Don't stomp on Glide/others: only touch the multiplier if it's ours or default
if (IsSprinting) controller.SpeedMultiplier = sprintMultiplier;
else if (Mathf.Approximately(controller.SpeedMultiplier, sprintMultiplier)) controller.SpeedMultiplier = 1f;
}
if (staminaSeconds > 0f)
{
float before = Stamina;
Stamina = IsSprinting ? Stamina - Time.deltaTime : Mathf.Min(staminaSeconds, Stamina + refillRate * Time.deltaTime);
if (Stamina <= 0f) { Stamina = 0f; if (toggleMode) held = false; }
if (!Mathf.Approximately(before, Stamina)) OnStaminaChanged?.Invoke(Stamina / staminaSeconds);
}
}
}