An experimental, status effects-as-entities system for Bevy.
0
fork

Configure Feed

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

Remove dedicated `lifetime` and `delay` fields from `EffectBundle`.

+55 -52
+3 -2
README.md
··· 31 31 For some effects it makes sense to allow stacking, so a single entity could be effected multiple times at once. 32 32 For others, each effect should only be applied once. 33 33 34 - Both behaviours are supported, and can be selected using an effect's `MergeMode`. 34 + Both behaviours are supported, and can be selected using an effect's `MergeMode`. Effects are consider the same if the entities have the same name. 35 35 36 36 | Mode | Behaviour | 37 37 |--------|-----------------------------------------------------------------------------------------| ··· 64 64 } 65 65 ``` 66 66 67 + ### Timers 68 + 67 69 ### Examples 68 - 69 70 70 71 ### Bevy Version Compatibility 71 72
+8 -6
examples/immediate_stats/decaying_speed.rs
··· 49 49 50 50 commands.entity(*target).with_effect(EffectBundle { 51 51 mode: EffectMode::Insert, // Block having multiple of effect stacked on a single target. 52 - lifetime: Some(Lifetime::from_seconds(2.0)), // The duration of the effect. 53 - bundle: DecayingSpeed { 54 - start_speed_boost: Modifier { 55 - bonus: 10, 56 - multiplier: 2.0, 52 + bundle: ( 53 + Lifetime::from_seconds(2.0), // The duration of the effect. 54 + DecayingSpeed { 55 + start_speed_boost: Modifier { 56 + bonus: 10, 57 + multiplier: 2.0, 58 + }, 57 59 }, 58 - }, 60 + ), 59 61 ..default() 60 62 }); 61 63 }
+8 -6
examples/immediate_stats/decaying_speed_auto_plugin.rs
··· 52 52 53 53 commands.entity(*target).with_effect(EffectBundle { 54 54 mode: EffectMode::Insert, // Block having multiple of effect stacked on a single target. 55 - lifetime: Some(Lifetime::from_seconds(2.0)), // The duration of the effect. 56 - bundle: DecayingSpeed { 57 - start_speed_boost: Modifier { 58 - bonus: 10, 59 - multiplier: 2.0, 55 + bundle: ( 56 + Lifetime::from_seconds(2.0), // The duration of the effect. 57 + DecayingSpeed { 58 + start_speed_boost: Modifier { 59 + bonus: 10, 60 + multiplier: 2.0, 61 + }, 60 62 }, 61 - }, 63 + ), 62 64 ..default() 63 65 }); 64 66 }
+5 -3
examples/poison.rs
··· 42 42 } 43 43 44 44 commands.entity(*target).with_effect(EffectBundle { 45 - lifetime: Some(Lifetime::from_seconds(4.0)), // The duration of the effect. 46 - delay: Some(Delay::from_seconds(1.0)), // The time between damage ticks. 47 - bundle: Poison { damage: 1 }, // The amount of damage to apply per tick. 45 + bundle: ( 46 + Lifetime::from_seconds(4.0), // The duration of the effect. 47 + Delay::from_seconds(1.0), // The time between damage ticks. 48 + Poison { damage: 1 }, // The amount of damage to apply per tick. 49 + ), 48 50 ..default() 49 51 }); 50 52 }
+1 -6
src/bundle.rs
··· 1 - use crate::{Delay, EffectMode, Lifetime}; 1 + use crate::EffectMode; 2 2 use bevy_ecs::prelude::*; 3 3 4 4 /// A "bundle" of components/settings used when applying an effect. ··· 19 19 pub name: Name, 20 20 /// Describes the logic used when new effect collides with an existing one. 21 21 pub mode: EffectMode, 22 - /// The duration of the effect. 23 - #[doc(alias = "duration")] 24 - pub lifetime: Option<Lifetime>, 25 - /// Repeating timer used for the delay between effect applications. 26 - pub delay: Option<Delay>, 27 22 /// Components that will be added to the effect. This is where the actual effect components get added. 28 23 pub bundle: B, 29 24 }
-8
src/command.rs
··· 35 35 self.bundle.mode, 36 36 self.bundle.bundle, 37 37 )); 38 - 39 - if let Some(lifetime) = self.bundle.lifetime { 40 - entity.insert(lifetime); 41 - } 42 - 43 - if let Some(delay) = self.bundle.delay { 44 - entity.insert(delay); 45 - } 46 38 } 47 39 48 40 /// Inserts into the existing entity, and then merges the old effect into it using [`EffectMergeRegistry`].
+30 -21
tests/merge_mode.rs
··· 126 126 let second_lifetime = Lifetime::from_seconds(2.0).with_mode(TimerMergeMode::Replace); 127 127 world.commands().entity(target).with_effect(EffectBundle { 128 128 mode: EffectMode::Merge, 129 - lifetime: Some(Lifetime::from_seconds(1.0).with_mode(TimerMergeMode::Replace)), 130 - bundle: MyEffect(0), 129 + bundle: ( 130 + Lifetime::from_seconds(1.0).with_mode(TimerMergeMode::Replace), 131 + MyEffect(0), 132 + ), 131 133 ..Default::default() 132 134 }); 133 135 world.commands().entity(target).with_effect(EffectBundle { 134 136 mode: EffectMode::Merge, 135 - lifetime: Some(second_lifetime.clone()), 136 - bundle: MyEffect(1), 137 + bundle: (second_lifetime.clone(), MyEffect(1)), 137 138 ..Default::default() 138 139 }); 139 140 ··· 157 158 let first_delay = Delay::from_seconds(1.0).with_mode(TimerMergeMode::Keep); 158 159 world.commands().entity(target).with_effect(EffectBundle { 159 160 mode: EffectMode::Merge, 160 - delay: Some(first_delay.clone()), 161 - bundle: MyEffect(0), 161 + bundle: (first_delay.clone(), MyEffect(0)), 162 162 ..Default::default() 163 163 }); 164 164 world.commands().entity(target).with_effect(EffectBundle { 165 165 mode: EffectMode::Merge, 166 - delay: Some(Delay::from_seconds(2.0).with_mode(TimerMergeMode::Keep)), 167 - bundle: MyEffect(1), 166 + bundle: ( 167 + Delay::from_seconds(2.0).with_mode(TimerMergeMode::Keep), 168 + MyEffect(1), 169 + ), 168 170 ..Default::default() 169 171 }); 170 172 ··· 190 192 191 193 world.commands().entity(target).with_effect(EffectBundle { 192 194 mode: EffectMode::Merge, 193 - delay: Some(Delay { 194 - timer: first_timer, 195 - mode: TimerMergeMode::Fraction, 196 - }), 197 - bundle: MyEffect(0), 195 + bundle: ( 196 + Delay { 197 + timer: first_timer, 198 + mode: TimerMergeMode::Fraction, 199 + }, 200 + MyEffect(0), 201 + ), 198 202 ..Default::default() 199 203 }); 200 204 world.commands().entity(target).with_effect(EffectBundle { 201 205 mode: EffectMode::Merge, 202 - delay: Some(Delay::from_seconds(10.0).with_mode(TimerMergeMode::Fraction)), 203 - bundle: MyEffect(1), 206 + bundle: ( 207 + Delay::from_seconds(10.0).with_mode(TimerMergeMode::Fraction), 208 + MyEffect(1), 209 + ), 204 210 ..Default::default() 205 211 }); 206 212 ··· 231 237 232 238 world.commands().entity(target).with_effect(EffectBundle { 233 239 mode: EffectMode::Merge, 234 - delay: Some(Delay::from_seconds(1.0).with_mode(TimerMergeMode::Max)), 235 - bundle: MyEffect(0), 240 + bundle: ( 241 + Delay::from_seconds(1.0).with_mode(TimerMergeMode::Max), 242 + MyEffect(0), 243 + ), 236 244 ..Default::default() 237 245 }); 238 246 world.commands().entity(target).with_effect(EffectBundle { 239 247 mode: EffectMode::Merge, 240 - delay: Some(max.clone()), 241 - bundle: MyEffect(1), 248 + bundle: (max.clone(), MyEffect(1)), 242 249 ..Default::default() 243 250 }); 244 251 world.commands().entity(target).with_effect(EffectBundle { 245 252 mode: EffectMode::Merge, 246 - delay: Some(Delay::from_seconds(2.0).with_mode(TimerMergeMode::Max)), 247 - bundle: MyEffect(2), 253 + bundle: ( 254 + Delay::from_seconds(2.0).with_mode(TimerMergeMode::Max), 255 + MyEffect(2), 256 + ), 248 257 ..Default::default() 249 258 }); 250 259