diff --git a/README.md b/README.md new file mode 100644 index 0000000..a74c7d8 --- /dev/null +++ b/README.md @@ -0,0 +1,73 @@ +# Immediate Stats + +Game stats that reset every frame. Inspired by immediate mode rendering. + +== Todo Info about derive macro. + +```rust no_run +use immediate_stats::*; + +#[derive(StatContainer)] +struct Speed(Stat); + +fn main() { + loop { + let mut speed = Speed(Stat::new(10)); // Set base speed to 10. + + speed.0 *= 2.0; // Applies a multiplier to the final result. + speed.0 += 5; // Adds a bonus to the final result. + // The order does not matter. Bonuses are always applied before multipliers. + assert_eq!(speed.0.total(), 30); // (10 + 5) * 2 = 30 + + speed.reset_modifiers(); // Reset bonus and multiplier, so speed is back to 10. + } +} +``` + +## Bevy + +There is build-in integration with the [Bevy Engine](https://bevyengine.org) via the `bevy` feature flag. +This adds systems for resetting `StatContainer` components and resources. + +```rust ignore +use bevy_app::prelude::*; +use bevy_ecs::prelude::*; +use immediate_stats::*; + +#[derive(StatContainer, Component, Resource)] +struct Speed(Stat); + +fn main() { + App::new() + .add_plugins(ImmediateStatesPlugin) + .add_systems(PreUpdate, ( + reset_component_modifiers::, + reset_resource_modifiers::, + )) + .run(); +} +``` + +### Bevy Butler + +If you use [Bevy Butler](https://github.com/TGRCdev/bevy-butler/), you can also use the `bevy_butler` feature flag. +This automatically registers the required system(s) using the `add_component` attribute. + +```rust ignore +use bevy_app::prelude::*; +use bevy_ecs::prelude::*; +use immediate_stats::*; +use bevy_butler::*; + +#[butler_plugin] +struct MyPlugin; + +#[derive(StatContainer, Component)] +#[add_component(plugin = MyPlugin)] // Added by `StatContainer` derive. +struct Speed(Stat); +``` + +### Version Compatibility +| bevy | immediate_stats | +|--------|-----------------| +| `0.16` | `0.1` | \ No newline at end of file diff --git a/immediate_stats/Cargo.toml b/immediate_stats/Cargo.toml index 071792b..f3de99c 100644 --- a/immediate_stats/Cargo.toml +++ b/immediate_stats/Cargo.toml @@ -23,3 +23,10 @@ bevy_ecs = { version = "0.16.0-rc", default-features = false, optional = true, f ] } bevy_reflect = { version = "0.16.0-rc", default-features = false, optional = true } immediate_stats_macros = { path = "../immediate_stats_macros", default-features = false } + +[lints.rust] +missing_docs = "warn" +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(docsrs_dep)'] } +unsafe_code = "deny" +unsafe_op_in_unsafe_fn = "warn" +unused_qualifications = "warn" diff --git a/immediate_stats/README.md b/immediate_stats/README.md new file mode 100644 index 0000000..a74c7d8 --- /dev/null +++ b/immediate_stats/README.md @@ -0,0 +1,73 @@ +# Immediate Stats + +Game stats that reset every frame. Inspired by immediate mode rendering. + +== Todo Info about derive macro. + +```rust no_run +use immediate_stats::*; + +#[derive(StatContainer)] +struct Speed(Stat); + +fn main() { + loop { + let mut speed = Speed(Stat::new(10)); // Set base speed to 10. + + speed.0 *= 2.0; // Applies a multiplier to the final result. + speed.0 += 5; // Adds a bonus to the final result. + // The order does not matter. Bonuses are always applied before multipliers. + assert_eq!(speed.0.total(), 30); // (10 + 5) * 2 = 30 + + speed.reset_modifiers(); // Reset bonus and multiplier, so speed is back to 10. + } +} +``` + +## Bevy + +There is build-in integration with the [Bevy Engine](https://bevyengine.org) via the `bevy` feature flag. +This adds systems for resetting `StatContainer` components and resources. + +```rust ignore +use bevy_app::prelude::*; +use bevy_ecs::prelude::*; +use immediate_stats::*; + +#[derive(StatContainer, Component, Resource)] +struct Speed(Stat); + +fn main() { + App::new() + .add_plugins(ImmediateStatesPlugin) + .add_systems(PreUpdate, ( + reset_component_modifiers::, + reset_resource_modifiers::, + )) + .run(); +} +``` + +### Bevy Butler + +If you use [Bevy Butler](https://github.com/TGRCdev/bevy-butler/), you can also use the `bevy_butler` feature flag. +This automatically registers the required system(s) using the `add_component` attribute. + +```rust ignore +use bevy_app::prelude::*; +use bevy_ecs::prelude::*; +use immediate_stats::*; +use bevy_butler::*; + +#[butler_plugin] +struct MyPlugin; + +#[derive(StatContainer, Component)] +#[add_component(plugin = MyPlugin)] // Added by `StatContainer` derive. +struct Speed(Stat); +``` + +### Version Compatibility +| bevy | immediate_stats | +|--------|-----------------| +| `0.16` | `0.1` | \ No newline at end of file diff --git a/immediate_stats/src/bevy/butler.rs b/immediate_stats/src/bevy/butler.rs index 8bc8117..eb0f570 100644 --- a/immediate_stats/src/bevy/butler.rs +++ b/immediate_stats/src/bevy/butler.rs @@ -6,12 +6,11 @@ mod tests { use bevy_app::App; use bevy_butler::*; use bevy_ecs::prelude::*; - use bevy_reflect::prelude::*; #[butler_plugin] struct MyPlugin; - #[derive(Reflect, Resource, Component, StatContainer, Default, PartialEq, Debug)] + #[derive(Resource, Component, StatContainer, Default, PartialEq, Debug)] #[add_component(plugin = MyPlugin)] #[add_resource(plugin = MyPlugin)] struct Health(Stat); diff --git a/immediate_stats/src/lib.rs b/immediate_stats/src/lib.rs index 82fa45e..feaa8fc 100644 --- a/immediate_stats/src/lib.rs +++ b/immediate_stats/src/lib.rs @@ -1,10 +1,18 @@ +#![doc = include_str!("../README.md")] + #[cfg(feature = "bevy")] pub mod bevy; pub mod stat; +// Todo Move into internal module called `__internal` like Bevy Butler. +#[cfg(feature = "bevy")] pub use bevy_app::prelude::PreUpdate; pub use immediate_stats_macros::StatContainer; +#[cfg(feature = "bevy")] +pub use bevy::*; +pub use stat::*; + /// Types that contain stats that need to be reset. /// /// It is recommended to use the [derive macro](macro) instead of implementing manually. diff --git a/immediate_stats/src/stat.rs b/immediate_stats/src/stat.rs index ce8d289..dee301f 100644 --- a/immediate_stats/src/stat.rs +++ b/immediate_stats/src/stat.rs @@ -17,8 +17,11 @@ use std::ops::{AddAssign, DivAssign, MulAssign, SubAssign}; /// [mul]:Stat::mul_assign /// [div]:Stat::div_assign #[derive(PartialEq, Debug, Copy, Clone)] -#[cfg_attr(feature = "bevy", derive(bevy_reflect::Reflect))] -#[reflect(PartialEq, Debug, Clone)] +#[cfg_attr( + feature = "bevy", + derive(bevy_reflect::Reflect), + reflect(PartialEq, Debug, Clone) +)] pub struct Stat { /// The persistent value of the stat. pub base: i32, diff --git a/immediate_stats/src/stat/modifier.rs b/immediate_stats/src/stat/modifier.rs index 8f46ee3..145580b 100644 --- a/immediate_stats/src/stat/modifier.rs +++ b/immediate_stats/src/stat/modifier.rs @@ -2,8 +2,11 @@ use std::ops::{AddAssign, DivAssign, MulAssign, SubAssign}; /// Modifier values that can be applied to a [`super::Stat`]. #[derive(PartialEq, Debug, Copy, Clone)] -#[cfg_attr(feature = "bevy", derive(bevy_reflect::Reflect))] -#[reflect(PartialEq, Debug, Clone)] +#[cfg_attr( + feature = "bevy", + derive(bevy_reflect::Reflect), + reflect(PartialEq, Debug, Clone) +)] pub struct Modifier { /// Added to `base` of a [`super::Stat`] during calculation. pub bonus: i32,