1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//! `bevy_gauge` is a flexible stat system for the Bevy game engine.
//!
//! It allows for defining complex character or item statistics with features like:
//! - Configurable stat types (e.g., flat values, tagged modifiers, modifiable bases).
//! - Expression-based calculations for total stat values.
//! - Modifiers that can be additive or multiplicative.
//! - Tagging system for fine-grained control over which modifiers apply.
//! - Dependencies between stats, including stats from different entities (sources).
//! - Caching of evaluated stat values for performance.
//! - Automatic cache invalidation when underlying values or dependencies change.
//! - Integration with Bevy's component system, allowing components to derive their fields
//! from stats or write their values back to stats.
//!
//! # Quick Start
//!
//! 1. **Add the plugin:**
//! ```no_run
//! use bevy::prelude::*;
//! use bevy_gauge::prelude::*;
//!
//! fn main() {
//! App::new()
//! .add_plugins(DefaultPlugins)
//! .add_plugins(bevy_gauge::plugin) // Add this line
//! // ... other app setup ...
//! .run();
//! }
//! ```
//!
//! 2. **Configure stats:** Create a `Config` resource and register your stat types
//! and how they are calculated.
//! ```no_run
//! use bevy::prelude::*;
//! use bevy_gauge::prelude::*;
//!
//! fn setup_config() {
//! Konfig::register_stat_type("Life", "Modifiable"); // Max health
//! Konfig::register_total_expression("Life", "base"); // Total is just its base
//!
//! Konfig::register_stat_type("Damage", "Tagged");
//! Konfig::register_total_expression("Damage", "base * (1.0 + increased) * more");
//! }
//!
//! fn main() {
//! setup_config();
//! App::new()
//! .add_plugins(DefaultPlugins)
//! .add_plugins(bevy_gauge::plugin)
//! // ...
//! .run();
//! }
//! ```
//!
//! 3. **Add `Stats` component to entities:**
//! ```no_run
//! # use bevy::prelude::*;
//! # use bevy_gauge::prelude::*;
//! fn spawn_player(mut commands: Commands) {
//! commands.spawn((PlayerTag, Stats::new()));
//! }
//! #[derive(Component)]
//! # struct PlayerTag;
//! ```
//!
//! 4. **Interact with stats using `StatsMutator` in systems:**
//! ```no_run
//! # use bevy::prelude::*;
//! # use bevy_gauge::prelude::*;
//! #[derive(Component)]
//! # struct PlayerTag;
//! # fn spawn_player(mut commands: Commands) { commands.spawn((PlayerTag, Stats::new())); }
//! fn apply_damage_buff(mut stats_mutator: StatsMutator, query: Query<Entity, With<PlayerTag>>) {
//! if let Ok(player_entity) = query.single() {
//! // Add a 20% increased damage modifier with tag 1 (e.g., "Fire")
//! stats_mutator.add_modifier(player_entity, "Damage.increased.1", 0.20);
//! }
//! }
//!
//! fn print_player_damage(stats_mutator: StatsMutator, query: Query<Entity, With<PlayerTag>>) {
//! if let Ok(player_entity) = query.single() {
//! // Evaluate total damage (no specific tag, so considers all relevant tags)
//! let total_damage = stats_mutator.evaluate(player_entity, "Damage");
//! // Evaluate fire damage (tag 1)
//! let fire_damage = stats_mutator.evaluate(player_entity, "Damage.1");
//! println!("Player Total Damage: {}, Fire Damage: {}", total_damage, fire_damage);
//! }
//! }
//! ```
//!
//! Check the `prelude` module for the most commonly used items.
//! The `StatsMutator` is the main entry point for interacting with entity stats from systems.
//! The `Config` resource is used for initial setup.
use *;
use *;
/// The main Bevy plugin for `bevy_gauge`.
///
/// Adds the necessary systems, resources, and configurations to integrate the stat system
/// into a Bevy application.
/// This includes setting up:
/// - An observer to clean up stats when entities with a `Stats` component are removed.
/// - The `app_extension::plugin` for custom schedules and derived/write-back component helpers.
///
/// This plugin should be added to your Bevy `App` for the stat system to function.
/// ```no_run
/// use bevy::prelude::*;
/// use bevy_gauge::plugin as BevyGaugePlugin;
///
/// fn main() {
/// App::new()
/// .add_plugins(DefaultPlugins)
/// .add_plugins(bevy_gauge::plugin)
/// // ... other app setup ...
/// .run();
/// }
/// ```