···11# Immediate Stats
2233-Game stats that reset every frame. Inspired by immediate mode rendering.
44-Includes a derive macro which propagates stat resets to any stat fields.
33+Game stats that reset every frame, inspired by immediate mode rendering.
44+55+This makes it easy to implement temporary buffs/debuffs, and effects that change over time.
66+Using a derive macro, stat resets are propagated to any stat fields,
77+making it easy to compose stats into more complex or specific objects.
5869```rust
710#[derive(StatContainer)]
+6-3
immediate_stats/README.md
···4343### Bevy Butler
44444545If you use [Bevy Butler](https://github.com/TGRCdev/bevy-butler/), you can also use the `bevy_butler` feature flag.
4646-This automatically registers the required system(s) using the `add_component` attribute.
4646+This automatically registers the required system(s) using the `add_component` attribute
4747+or the existing `add_resource` macro.
47484849```rust
4950#[butler_plugin]
5051struct MyPlugin;
51525252-#[derive(StatContainer, Component)]
5353-#[add_component(plugin = MyPlugin)] // Added by `StatContainer` derive.
5353+// `StatContainer` derive adds the `add_component` attribute and hooks into the existing `add_resource` macro.
5454+#[derive(StatContainer, Component, Resource, Default)]
5555+#[add_component(plugin = MyPlugin)] // Adds `reset_component_modifiers` system.
5656+#[add_resource(plugin = MyPlugin)] // Adds `reset_resource_modifiers` system.
5457struct Speed(Stat);
5558```
5659
+1-1
immediate_stats/src/bevy.rs
···2222 }
2323}
24242525-/// Prevents a [`StatContainers`](StatContainer) from resetting.
2525+/// Prevents any [`StatContainers`](StatContainer) on an entity from resetting.
2626#[derive(Component, Reflect, Eq, PartialEq, Debug, Default, Clone)]
2727#[component(storage = "SparseSet")]
2828#[reflect(Component, PartialEq, Debug, Default, Clone)]
+15-12
immediate_stats/src/lib.rs
···11-//! Game stats that reset every frame.
22-//! Inspired by immediate mode rendering.
11+//! Game stats that reset every frame, inspired by immediate mode rendering.
32//!
44-//! Includes a [derive macro](macro@StatContainer) which propagates stat resets to any stat fields.
33+//! This makes it easy to implement temporary buffs/debuffs, and effects that change over time.
44+//! Using a [derive macro](macro@StatContainer), stat resets are propagated to any stat fields,
55+//! making it easy to compose stats into more complex or specific objects.
56//!
67//! ```rust no_run
78//! # use immediate_stats::*;
···5051//!
5152//! If you use [Bevy Butler](https://github.com/TGRCdev/bevy-butler/),
5253//! you can also use the `bevy_butler` feature flag.
5353-//! This automatically registers the required system(s) using the `add_component` attribute.
5454+//! This automatically registers the required system(s) using the `add_component` attribute
5555+//! or the existing `add_resource` macro.
5456//!
5557#![cfg_attr(not(feature = "bevy_butler"), doc = "```rust ignore")]
5658#![cfg_attr(feature = "bevy_butler", doc = "```rust")]
···8082mod stat;
81838284/// Implements [`reset_modifiers`](StatContainer::reset_modifiers)
8383-/// by propagating the call down to any `StatContainer` fields.
8585+/// by propagating the call down to any stat fields.
8486/// ```rust
8587/// # use immediate_stats::*;
8688/// #[derive(StatContainer, Default, Debug, PartialEq)]
···101103/// }
102104/// ```
103105/// # Configuration
104104-/// By default, it will consider any field whose type contains "Stat" to be a sub-stat.
106106+/// By default, the macro will consider any field whose type contains the word "Stat"
107107+/// to be a sub-stat.
105108/// You can use `#[stat]` to add other sub-stats and `#[stat_ignore]` to ignore one.
106109/// ```rust
107110/// # use immediate_stats::*;
···121124/// fn main () {
122125/// let mut partial = PartialReset {
123126/// custom: Health::default(),
124124-/// ignored: Stat::new(1),
127127+/// ignored: Stat::default(),
125128/// };
126129///
127130/// partial.custom.max += 10;
···130133/// partial.reset_modifiers();
131134///
132135/// assert_eq!(partial.custom, Health::default());
133133-/// assert_eq!(partial.ignored, Stat::new(1).with_bonus(10));
136136+/// assert_eq!(partial.ignored, Stat::default().with_bonus(10));
134137/// }
135138/// ```
136139/// # Bevy Butler
137140/// If the `bevy_butler` feature flag is enabled, you may also use the `add_component` attribute
138138-/// to register [`reset_component_modifiers`] and/or [`reset_resource_modifiers`] automatically.
141141+/// or the existing `add_resource` macro to register [`reset_component_modifiers`]
142142+/// and/or [`reset_resource_modifiers`] automatically.
139143#[cfg_attr(not(feature = "bevy_butler"), doc = "```rust ignore")]
140144#[cfg_attr(feature = "bevy_butler", doc = "```rust")]
141145/// # use bevy_butler::*;
···165169166170/// Types that contain stats that need to be reset.
167171///
168168-/// It is recommended to use the [derive macro](macro@StatContainer)
169169-/// instead of implementing manually.
172172+/// Consider using the [derive macro](macro@StatContainer) before implementing manually.
170173#[cfg_attr(feature = "bevy", bevy_reflect::reflect_trait)]
171174pub trait StatContainer {
172172- /// Resets all stat bonuses to zero, and stat multipliers to one.
175175+ /// Resets all stats to a base value. For most use-cases, this should be called every frame/iteration.
173176 fn reset_modifiers(&mut self);
174177}
+10-2
immediate_stats/src/modifier.rs
···1010 reflect(PartialEq, Debug, Clone)
1111)]
1212pub struct Modifier {
1313- /// Added to `base` of a [`super::Stat`] during calculation.
1313+ /// Added to `base` of a [`Stat`](super::Stat) during calculation.
1414+ ///
1515+ /// Can be modified using [`+=`](Modifier::add_assign) and [`-=`](`Modifier::sub_assign`).
1416 pub bonus: i32,
1515- /// Multiplies the `base` of a [`super::Stat`] during calculation.
1717+ /// Multiplies the `base` of a [`Stat`](super::Stat) during calculation.
1818+ ///
1919+ /// Can be modified using [`*=`](`Modifier::mul_assign`) and [`/=`](`Modifier::div_assign`).
1620 pub multiplier: f32,
1721}
1822···4953}
50545155impl AddAssign<i32> for Modifier {
5656+ /// Adds to the modifier's bonus.
5257 fn add_assign(&mut self, rhs: i32) {
5358 self.bonus += rhs;
5459 }
5560}
56615762impl SubAssign<i32> for Modifier {
6363+ /// Subtracts from the modifier's bonus.
5864 fn sub_assign(&mut self, rhs: i32) {
5965 self.bonus -= rhs;
6066 }
6167}
62686369impl MulAssign<f32> for Modifier {
7070+ /// Multiplies the modifier's multiplier.
6471 fn mul_assign(&mut self, rhs: f32) {
6572 self.multiplier *= rhs;
6673 }
6774}
68756976impl DivAssign<f32> for Modifier {
7777+ /// Divides the modifier's multiplier.
7078 fn div_assign(&mut self, rhs: f32) {
7179 self.multiplier /= rhs;
7280 }
+7-2
immediate_stats/src/stat.rs
···2424)]
2525pub struct Stat {
2626 /// The persistent value of the stat.
2727+ /// After being [reset](StatContainer::reset_modifiers), [`Stat::total`] will be equal to `base`.
2728 pub base: i32,
2829 /// Added to `base` during calculation and gets reset to zero every iteration.
2930 /// This is added *before* `multiplier` is applied.
3031 ///
3131- /// Can be modified using [`Stat::add_assign`] and [`Stat::sub_assign`]
3232+ /// Can be modified using [`+=`](Stat::add_assign) or [`-=`](Stat::sub_assign).
3233 pub bonus: i32,
3334 /// Multiplies the `base` during calculation and gets reset to one every iteration.
3435 /// This is applied *after* `bonus` is added.
3536 ///
3636- /// Can be modified using [`Stat::mul_assign`] and [`Stat::div_assign`]
3737+ /// Can be modified using [*=](`Stat::mul_assign`) or [/=](`Stat::div_assign`).
3738 pub multiplier: f32,
3839}
3940···9798}
989999100impl AddAssign<i32> for Stat {
101101+ /// Adds to the stat's bonus.
100102 fn add_assign(&mut self, rhs: i32) {
101103 self.bonus += rhs;
102104 }
103105}
104106105107impl SubAssign<i32> for Stat {
108108+ /// Subtracts from the stat's bonus.
106109 fn sub_assign(&mut self, rhs: i32) {
107110 self.bonus -= rhs;
108111 }
109112}
110113111114impl MulAssign<f32> for Stat {
115115+ /// Multiplies the stat's multiplier.
112116 fn mul_assign(&mut self, rhs: f32) {
113117 self.multiplier *= rhs;
114118 }
115119}
116120117121impl DivAssign<f32> for Stat {
122122+ /// Divides the stat's multiplier.
118123 fn div_assign(&mut self, rhs: f32) {
119124 self.multiplier /= rhs;
120125 }