···4455This makes it easy to implement temporary buffs/debuffs, and effects that change over time.
66Using a derive macro, stat resets are propagated to any stat fields,
77-making it easy to compose stats into more complex or specific objects.
77+making it easy to compose stats into more complex objects.
8899```rust
1010#[derive(StatContainer)]
···1616 loop {
1717 speed.0 *= 2.0; // Applies a multiplier to the final result.
1818 speed.0 += 5; // Adds a bonus to the final result.
1919- // The order does not matter. Bonuses are always applied before multipliers.
1919+ // The order does not matter, bonuses are always applied before multipliers.
2020 assert_eq!(speed.0.total(), 30); // (10 + 5) * 2 = 30
21212222 speed.reset_modifiers(); // Reset bonus and multiplier, so speed is back to 10.
···2727## Bevy
28282929There is build-in integration with the [Bevy Engine](https://bevyengine.org) via the `bevy` feature flag.
3030-This adds systems for resetting `StatContainer` components and resources.
3030+This adds plugins for resetting `StatContainer` components and resources.
31313232```rust
3333#[derive(StatContainer, Component, Resource)]
···3636fn main() {
3737 App::new()
3838 .add_plugins((
3939+ ImmediateStatsPlugin,
3940 ResetComponentPlugin::<Speed>::new(),
4041 ResetResourcePlugin::<Speed>::new(),
4142 ))
···5051or the existing `insert_resource` macro.
51525253```rust
5454+fn main() {
5555+ App::new().add_plugins((ImmediateStatsPlugin, MyPlugin)).run();
5656+}
5757+5358#[butler_plugin]
5459struct MyPlugin;
5560
+17-12
immediate_stats/examples/simple_bevy.rs
···55use immediate_stats::*;
6677fn main() {
88- App::new().add_plugins((MinimalPlugins, SpeedPlugin)).run();
88+ App::new()
99+ .add_plugins((MinimalPlugins, ImmediateStatsPlugin, SpeedPlugin))
1010+ .run();
911}
10121113struct SpeedPlugin;
12141315impl Plugin for SpeedPlugin {
1416 fn build(&self, app: &mut App) {
1515- app.add_plugins((ImmediateStatsPlugin, ResetComponentPlugin::<Speed>::new()))
1616- .add_systems(Startup, init_speed)
1717- .add_systems(
1818- Update,
1919- (
2020- // Modifiers must be applied before the speed can be read.
2121- apply_modifiers.in_set(StatSystems::Modify),
2222- read_speed.in_set(StatSystems::Read),
2323- ),
2424- );
1717+ app.add_plugins(
1818+ ResetComponentPlugin::<Speed>::new(), // Reset modifiers, so speed is back to 10.
1919+ )
2020+ .add_systems(Startup, init_speed)
2121+ .add_systems(
2222+ Update,
2323+ (
2424+ // Modifiers must be applied before the speed can be read.
2525+ apply_modifiers.in_set(StatSystems::Modify),
2626+ read_speed.in_set(StatSystems::Read),
2727+ ),
2828+ );
2529 }
2630}
27313232+// Implements `reset_modifiers` by passing the call onto `Stat`.
2833#[derive(StatContainer, Component)]
2934struct Speed(Stat);
3035···3641 for mut speed in &mut speeds {
3742 speed.0 *= 2.0; // Applies a multiplier to the final result.
3843 speed.0 += 5; // Adds a bonus to the final result.
3939- // The order does not matter. Bonuses are always applied before multipliers.
4444+ // The order does not matter, bonuses are always applied before multipliers.
4045 }
4146}
4247
+3-1
immediate_stats/examples/simple_bevy_butler.rs
···1414#[butler_plugin]
1515struct SpeedPlugin;
16161717+// Implements `reset_modifiers` by passing the call onto `Stat`.
1818+// This will also add the `ResetComponentPlugin` to `SpeedPlugin`.
1719#[derive(StatContainer, Component)]
1820#[add_component(plugin = SpeedPlugin)]
1921struct Speed(Stat);
···2830 for mut speed in &mut speeds {
2931 speed.0 *= 2.0; // Applies a multiplier to the final result.
3032 speed.0 += 5; // Adds a bonus to the final result.
3131- // The order does not matter. Bonuses are always applied before multipliers.
3333+ // The order does not matter, bonuses are always applied before multipliers.
3234 }
3335}
3436
+2-1
immediate_stats/examples/simple_main_loop.rs
···3344use immediate_stats::*;
5566+// Implements `reset_modifiers` by passing the call onto `Stat`.
67#[derive(StatContainer)]
78struct Speed(Stat);
89···1314 // 1. Apply modifiers:
1415 speed.0 *= 2.0; // Applies a multiplier to the final result.
1516 speed.0 += 5; // Adds a bonus to the final result.
1616- // The order does not matter. Bonuses are always applied before multipliers.
1717+ // The order does not matter, bonuses are always applied before multipliers.
17181819 // 2. Read total:
1920 println!("The current speed is {}.", speed.0.total());
+6-3
immediate_stats/src/bevy.rs
···4040 Read,
4141}
42424343-/// Prevents any [`StatContainers`](StatContainer) on an entity from resetting.
4343+/// Prevents all [`StatContainers`](StatContainer)
4444+/// on an entity from getting reset by [`ResetComponentPlugin`].
4445#[derive(Component, Reflect, Eq, PartialEq, Debug, Default, Clone)]
4546#[component(storage = "SparseSet")]
4647#[reflect(Component, PartialEq, Debug, Default, Clone)]
4748pub struct PauseStatReset;
48494950/// Calls [`reset_modifiers`](StatContainer::reset_modifiers) on all `T` components.
5151+/// This can be paused on a per-entity basis using the [`PauseStatReset`] component.
5052///
5151-/// Reset occurs in the [`Reset`](StatSystems::Reset) system set during [`PreUpdate`].
5353+/// Reset occurs in the [`Reset`](StatSystems::Reset) system set during `PreUpdate`.
5254pub struct ResetComponentPlugin<T: Component<Mutability = Mutable> + StatContainer> {
5355 _phantom: PhantomData<T>,
5456}
···6365}
64666567/// Calls [`reset_modifiers`](StatContainer::reset_modifiers) on all `T` components.
6868+/// This can be paused on a per-entity basis using the [`PauseStatReset`] component.
6669///
6770/// Use the [`ResetResourcePlugin`] for recommended configuration.
6871pub fn reset_component_modifiers<T: Component<Mutability = Mutable> + StatContainer>(
···90939194/// Calls [`reset_modifiers`](StatContainer::reset_modifiers) on the `T` resource, if it exists.
9295///
9393-/// Reset occurs in the [`Reset`](StatSystems::Reset) system set during [`PreUpdate`].
9696+/// Reset occurs in the [`Reset`](StatSystems::Reset) system set during `PreUpdate`.
9497pub struct ResetResourcePlugin<T: Resource + StatContainer> {
9598 _phantom: PhantomData<T>,
9699}
+11-6
immediate_stats/src/lib.rs
···22//!
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.
55+//! making it easy to compose stats into more complex objects.
66//!
77//! ```rust no_run
88//! # use immediate_stats::*;
···1010//! struct Speed(Stat);
1111//!
1212//! fn main() {
1313+//! let mut speed = Speed(Stat::new(10)); // Set base speed to 10.
1414+//!
1315//! loop {
1414-//! let mut speed = Speed(Stat::new(10)); // Set base speed to 10.
1515-//!
1616//! speed.0 *= 2.0; // Applies a multiplier to the final result.
1717//! speed.0 += 5; // Adds a bonus to the final result.
1818-//! // The order does not matter. Bonuses are always applied before multipliers.
1818+//! // The order does not matter, bonuses are always applied before multipliers.
1919//! assert_eq!(speed.0.total(), 30); // (10 + 5) * 2 = 30
2020//!
2121//! speed.reset_modifiers(); // Reset speed back to 10.
···4040//! fn main() {
4141//! App::new()
4242//! .add_plugins((
4343+//! ImmediateStatsPlugin,
4344//! ResetComponentPlugin::<Speed>::new(),
4445//! ResetResourcePlugin::<Speed>::new(),
4546//! ))
···6061//! # use bevy_ecs::prelude::*;
6162//! # use immediate_stats::*;
6263//! # use bevy_butler::*;
6464+//! fn main() {
6565+//! App::new().add_plugins((ImmediateStatsPlugin, MyPlugin)).run();
6666+//! }
6767+//!
6368//! #[butler_plugin]
6469//! struct MyPlugin;
6570//!
6671//! // `StatContainer` derive adds the `add_component` attribute
6772//! // and hooks into the existing `insert_resource` macro.
6873//! #[derive(StatContainer, Component, Resource, Default)]
6969-//! #[add_component(plugin = MyPlugin)] // Adds `reset_component_modifiers` system.
7070-//! #[insert_resource(plugin = MyPlugin)] // Adds `reset_resource_modifiers` system.
7474+//! #[add_component(plugin = MyPlugin)] // Adds `ResetComponentPlugin`
7575+//! #[insert_resource(plugin = MyPlugin)] // Adds `ResetResourcePlugin`
7176//! struct Speed(Stat);
7277//! ```
7378//!
+1-1
immediate_stats/src/modifier.rs
···1010 reflect(PartialEq, Debug, Clone)
1111)]
1212pub struct Modifier {
1313- /// Added to `base` of a [`Stat`](super::Stat) during calculation.
1313+ /// Added to the `base` of a [`Stat`](super::Stat) during calculation.
1414 ///
1515 /// Can be modified using [`+=`](Modifier::add_assign) and [`-=`](`Modifier::sub_assign`).
1616 pub bonus: i32,
+5-5
immediate_stats/src/stat.rs
···99/// Temporary bonuses can be applied using [`+=`][add], [`-=`][sub], [`*=`][mul], and [`/=`][div].
1010/// During [calculation](Stat::total),
1111/// multiplication and division are always applied **after** addition and subtraction.
1212-/// These bonuses are reset when [`reset_modifiers`][reset] is called.
1212+/// These modifiers are reset when [`reset_modifiers`][reset] is called.
1313///
1414/// [reset]: StatContainer::reset_modifiers
1515/// [add]: Stat::add_assign
···2626 /// The persistent value of the stat.
2727 /// After being [reset](StatContainer::reset_modifiers), [`Stat::total`] will be equal to `base`.
2828 pub base: i32,
2929- /// Added to `base` during calculation and gets reset to zero every iteration.
3030- /// This is added *before* `multiplier` is applied.
2929+ /// Added to `base` during calculation and gets [reset](StatContainer::reset_modifiers) to zero.
3030+ /// This is added **before** `multiplier` is applied.
3131 ///
3232 /// Can be modified using [`+=`](Stat::add_assign) or [`-=`](Stat::sub_assign).
3333 pub bonus: i32,
3434 /// Multiplies the `base` during calculation and gets reset to one every iteration.
3535- /// This is applied *after* `bonus` is added.
3535+ /// This is applied **after** `bonus` is added.
3636 ///
3737- /// Can be modified using [*=](`Stat::mul_assign`) or [/=](`Stat::div_assign`).
3737+ /// Can be modified using [`*=`](`Stat::mul_assign`) or [`/=`](`Stat::div_assign`).
3838 pub multiplier: f32,
3939}
4040