Game stats that reset every frame, inspired by immediate mode GUI.
gamedev bevy stats
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #5 from AlephCubed/dev

Documentation Improvements.

authored by

AlephCubed and committed by
GitHub
80accda6 ba32f1ae

+44 -22
+5 -2
README.md
··· 1 1 # Immediate Stats 2 2 3 - Game stats that reset every frame. Inspired by immediate mode rendering. 4 - Includes a derive macro which propagates stat resets to any stat fields. 3 + Game stats that reset every frame, inspired by immediate mode rendering. 4 + 5 + This makes it easy to implement temporary buffs/debuffs, and effects that change over time. 6 + Using a derive macro, stat resets are propagated to any stat fields, 7 + making it easy to compose stats into more complex or specific objects. 5 8 6 9 ```rust 7 10 #[derive(StatContainer)]
+6 -3
immediate_stats/README.md
··· 43 43 ### Bevy Butler 44 44 45 45 If you use [Bevy Butler](https://github.com/TGRCdev/bevy-butler/), you can also use the `bevy_butler` feature flag. 46 - This automatically registers the required system(s) using the `add_component` attribute. 46 + This automatically registers the required system(s) using the `add_component` attribute 47 + or the existing `add_resource` macro. 47 48 48 49 ```rust 49 50 #[butler_plugin] 50 51 struct MyPlugin; 51 52 52 - #[derive(StatContainer, Component)] 53 - #[add_component(plugin = MyPlugin)] // Added by `StatContainer` derive. 53 + // `StatContainer` derive adds the `add_component` attribute and hooks into the existing `add_resource` macro. 54 + #[derive(StatContainer, Component, Resource, Default)] 55 + #[add_component(plugin = MyPlugin)] // Adds `reset_component_modifiers` system. 56 + #[add_resource(plugin = MyPlugin)] // Adds `reset_resource_modifiers` system. 54 57 struct Speed(Stat); 55 58 ``` 56 59
+1 -1
immediate_stats/src/bevy.rs
··· 22 22 } 23 23 } 24 24 25 - /// Prevents a [`StatContainers`](StatContainer) from resetting. 25 + /// Prevents any [`StatContainers`](StatContainer) on an entity from resetting. 26 26 #[derive(Component, Reflect, Eq, PartialEq, Debug, Default, Clone)] 27 27 #[component(storage = "SparseSet")] 28 28 #[reflect(Component, PartialEq, Debug, Default, Clone)]
+15 -12
immediate_stats/src/lib.rs
··· 1 - //! Game stats that reset every frame. 2 - //! Inspired by immediate mode rendering. 1 + //! Game stats that reset every frame, inspired by immediate mode rendering. 3 2 //! 4 - //! Includes a [derive macro](macro@StatContainer) which propagates stat resets to any stat fields. 3 + //! This makes it easy to implement temporary buffs/debuffs, and effects that change over time. 4 + //! Using a [derive macro](macro@StatContainer), stat resets are propagated to any stat fields, 5 + //! making it easy to compose stats into more complex or specific objects. 5 6 //! 6 7 //! ```rust no_run 7 8 //! # use immediate_stats::*; ··· 50 51 //! 51 52 //! If you use [Bevy Butler](https://github.com/TGRCdev/bevy-butler/), 52 53 //! you can also use the `bevy_butler` feature flag. 53 - //! This automatically registers the required system(s) using the `add_component` attribute. 54 + //! This automatically registers the required system(s) using the `add_component` attribute 55 + //! or the existing `add_resource` macro. 54 56 //! 55 57 #![cfg_attr(not(feature = "bevy_butler"), doc = "```rust ignore")] 56 58 #![cfg_attr(feature = "bevy_butler", doc = "```rust")] ··· 80 82 mod stat; 81 83 82 84 /// Implements [`reset_modifiers`](StatContainer::reset_modifiers) 83 - /// by propagating the call down to any `StatContainer` fields. 85 + /// by propagating the call down to any stat fields. 84 86 /// ```rust 85 87 /// # use immediate_stats::*; 86 88 /// #[derive(StatContainer, Default, Debug, PartialEq)] ··· 101 103 /// } 102 104 /// ``` 103 105 /// # Configuration 104 - /// By default, it will consider any field whose type contains "Stat" to be a sub-stat. 106 + /// By default, the macro will consider any field whose type contains the word "Stat" 107 + /// to be a sub-stat. 105 108 /// You can use `#[stat]` to add other sub-stats and `#[stat_ignore]` to ignore one. 106 109 /// ```rust 107 110 /// # use immediate_stats::*; ··· 121 124 /// fn main () { 122 125 /// let mut partial = PartialReset { 123 126 /// custom: Health::default(), 124 - /// ignored: Stat::new(1), 127 + /// ignored: Stat::default(), 125 128 /// }; 126 129 /// 127 130 /// partial.custom.max += 10; ··· 130 133 /// partial.reset_modifiers(); 131 134 /// 132 135 /// assert_eq!(partial.custom, Health::default()); 133 - /// assert_eq!(partial.ignored, Stat::new(1).with_bonus(10)); 136 + /// assert_eq!(partial.ignored, Stat::default().with_bonus(10)); 134 137 /// } 135 138 /// ``` 136 139 /// # Bevy Butler 137 140 /// If the `bevy_butler` feature flag is enabled, you may also use the `add_component` attribute 138 - /// to register [`reset_component_modifiers`] and/or [`reset_resource_modifiers`] automatically. 141 + /// or the existing `add_resource` macro to register [`reset_component_modifiers`] 142 + /// and/or [`reset_resource_modifiers`] automatically. 139 143 #[cfg_attr(not(feature = "bevy_butler"), doc = "```rust ignore")] 140 144 #[cfg_attr(feature = "bevy_butler", doc = "```rust")] 141 145 /// # use bevy_butler::*; ··· 165 169 166 170 /// Types that contain stats that need to be reset. 167 171 /// 168 - /// It is recommended to use the [derive macro](macro@StatContainer) 169 - /// instead of implementing manually. 172 + /// Consider using the [derive macro](macro@StatContainer) before implementing manually. 170 173 #[cfg_attr(feature = "bevy", bevy_reflect::reflect_trait)] 171 174 pub trait StatContainer { 172 - /// Resets all stat bonuses to zero, and stat multipliers to one. 175 + /// Resets all stats to a base value. For most use-cases, this should be called every frame/iteration. 173 176 fn reset_modifiers(&mut self); 174 177 }
+10 -2
immediate_stats/src/modifier.rs
··· 10 10 reflect(PartialEq, Debug, Clone) 11 11 )] 12 12 pub struct Modifier { 13 - /// Added to `base` of a [`super::Stat`] during calculation. 13 + /// Added to `base` of a [`Stat`](super::Stat) during calculation. 14 + /// 15 + /// Can be modified using [`+=`](Modifier::add_assign) and [`-=`](`Modifier::sub_assign`). 14 16 pub bonus: i32, 15 - /// Multiplies the `base` of a [`super::Stat`] during calculation. 17 + /// Multiplies the `base` of a [`Stat`](super::Stat) during calculation. 18 + /// 19 + /// Can be modified using [`*=`](`Modifier::mul_assign`) and [`/=`](`Modifier::div_assign`). 16 20 pub multiplier: f32, 17 21 } 18 22 ··· 49 53 } 50 54 51 55 impl AddAssign<i32> for Modifier { 56 + /// Adds to the modifier's bonus. 52 57 fn add_assign(&mut self, rhs: i32) { 53 58 self.bonus += rhs; 54 59 } 55 60 } 56 61 57 62 impl SubAssign<i32> for Modifier { 63 + /// Subtracts from the modifier's bonus. 58 64 fn sub_assign(&mut self, rhs: i32) { 59 65 self.bonus -= rhs; 60 66 } 61 67 } 62 68 63 69 impl MulAssign<f32> for Modifier { 70 + /// Multiplies the modifier's multiplier. 64 71 fn mul_assign(&mut self, rhs: f32) { 65 72 self.multiplier *= rhs; 66 73 } 67 74 } 68 75 69 76 impl DivAssign<f32> for Modifier { 77 + /// Divides the modifier's multiplier. 70 78 fn div_assign(&mut self, rhs: f32) { 71 79 self.multiplier /= rhs; 72 80 }
+7 -2
immediate_stats/src/stat.rs
··· 24 24 )] 25 25 pub struct Stat { 26 26 /// The persistent value of the stat. 27 + /// After being [reset](StatContainer::reset_modifiers), [`Stat::total`] will be equal to `base`. 27 28 pub base: i32, 28 29 /// Added to `base` during calculation and gets reset to zero every iteration. 29 30 /// This is added *before* `multiplier` is applied. 30 31 /// 31 - /// Can be modified using [`Stat::add_assign`] and [`Stat::sub_assign`] 32 + /// Can be modified using [`+=`](Stat::add_assign) or [`-=`](Stat::sub_assign). 32 33 pub bonus: i32, 33 34 /// Multiplies the `base` during calculation and gets reset to one every iteration. 34 35 /// This is applied *after* `bonus` is added. 35 36 /// 36 - /// Can be modified using [`Stat::mul_assign`] and [`Stat::div_assign`] 37 + /// Can be modified using [*=](`Stat::mul_assign`) or [/=](`Stat::div_assign`). 37 38 pub multiplier: f32, 38 39 } 39 40 ··· 97 98 } 98 99 99 100 impl AddAssign<i32> for Stat { 101 + /// Adds to the stat's bonus. 100 102 fn add_assign(&mut self, rhs: i32) { 101 103 self.bonus += rhs; 102 104 } 103 105 } 104 106 105 107 impl SubAssign<i32> for Stat { 108 + /// Subtracts from the stat's bonus. 106 109 fn sub_assign(&mut self, rhs: i32) { 107 110 self.bonus -= rhs; 108 111 } 109 112 } 110 113 111 114 impl MulAssign<f32> for Stat { 115 + /// Multiplies the stat's multiplier. 112 116 fn mul_assign(&mut self, rhs: f32) { 113 117 self.multiplier *= rhs; 114 118 } 115 119 } 116 120 117 121 impl DivAssign<f32> for Stat { 122 + /// Divides the stat's multiplier. 118 123 fn div_assign(&mut self, rhs: f32) { 119 124 self.multiplier /= rhs; 120 125 }