generated from Leafwing-Studios/template-repo
-
Notifications
You must be signed in to change notification settings - Fork 108
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add very simple cooldowns * Add cooldowns to ActionState and ActionData * Add trigger and can_trigger methods to `ActionState` * Clean up and demo API for ActionState cooldowns * Update release notes
- Loading branch information
1 parent
5ba68f2
commit 283d1d4
Showing
5 changed files
with
197 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
//! Cooldowns tick down until actions are ready to be used. | ||
|
||
use bevy::utils::Duration; | ||
use serde::{Deserialize, Serialize}; | ||
|
||
/// A timer-like struct that records the amount of time until an action is available to be used again. | ||
/// | ||
/// Cooldowns are typically stored in an [`ActionState`](crate::action_state::ActionState), associated with an action that is to be | ||
/// cooldown-regulated. | ||
/// | ||
/// When initialized, cooldowns are always fully available. | ||
/// | ||
/// ```rust | ||
/// use bevy::utils::Duration; | ||
/// use leafwing_input_manager::cooldown::Cooldown; | ||
/// | ||
/// let mut cooldown = Cooldown::new(Duration::from_secs(3)); | ||
/// assert_eq!(cooldown.time_remaining(), Duration::ZERO); | ||
/// | ||
/// cooldown.trigger(); | ||
/// assert_eq!(cooldown.time_remaining(), Duration::from_secs(3)); | ||
/// | ||
/// cooldown.tick(Duration::from_secs(1)); | ||
/// assert!(!cooldown.ready()); | ||
/// | ||
/// cooldown.tick(Duration::from_secs(5)); | ||
/// let triggered = cooldown.trigger(); | ||
/// assert!(triggered); | ||
/// | ||
/// cooldown.refresh(); | ||
/// assert!(cooldown.ready()); | ||
/// ``` | ||
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)] | ||
pub struct Cooldown { | ||
max_time: Duration, | ||
time_remaining: Duration, | ||
} | ||
|
||
impl Cooldown { | ||
/// Creates a new [`Cooldown`], which will take `max_time` after it is used until it is ready again. | ||
pub fn new(max_time: Duration) -> Cooldown { | ||
Cooldown { | ||
max_time, | ||
time_remaining: Duration::ZERO, | ||
} | ||
} | ||
|
||
/// Advance the cooldown by `delta_time`. | ||
pub fn tick(&mut self, delta_time: Duration) { | ||
self.time_remaining = self.time_remaining.saturating_sub(delta_time); | ||
} | ||
|
||
/// Is this action ready to be used? | ||
/// | ||
/// This will be true if and only if the `time_remaining` is [`Duration::Zero`]. | ||
pub fn ready(&self) -> bool { | ||
self.time_remaining == Duration::ZERO | ||
} | ||
|
||
/// Refreshes the cooldown, causing the underlying action to be ready to use immediately. | ||
pub fn refresh(&mut self) { | ||
self.time_remaining = Duration::ZERO; | ||
} | ||
|
||
/// Use the underlying cooldown if and only if it is ready, resetting the cooldown to its maximum value. | ||
/// | ||
/// Returns a boolean indicating whether the cooldown was ready. | ||
pub fn trigger(&mut self) -> bool { | ||
if self.ready() { | ||
self.time_remaining = self.max_time; | ||
true | ||
} else { | ||
false | ||
} | ||
} | ||
|
||
/// Returns the time that it will take for this action to be ready to use again after being triggered. | ||
pub fn max_time(&self) -> Duration { | ||
self.max_time | ||
} | ||
|
||
/// Sets the time that it will take for this action to be ready to use again after being triggered. | ||
/// | ||
/// If the current time remaining is greater than the new max time, it will be clamped to the `max_time`. | ||
pub fn set_max_time(&mut self, max_time: Duration) { | ||
self.max_time = max_time; | ||
self.time_remaining = self.time_remaining.min(max_time); | ||
} | ||
|
||
/// Returns the time remaining until the action is ready to use again. | ||
pub fn time_remaining(&self) -> Duration { | ||
self.time_remaining | ||
} | ||
|
||
/// Sets the time remaining until the action is ready to use again. | ||
/// | ||
/// This will always be clamped between [`Duration::ZERO`] and the `max_time` of this cooldown. | ||
pub fn set_time_remaining(&mut self, time_remaining: Duration) { | ||
self.time_remaining = time_remaining.clamp(Duration::ZERO, self.max_time); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters