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.

Moved tests into seperate directory.

+290 -316
-46
bevy_status_effects/src/bevy_butler.rs
··· 1 - #[cfg(test)] 2 - mod tests { 3 - use crate as bevy_status_effects; 4 - use crate::EffectMode; 5 - use crate::relation::Effecting; 6 - use bevy_app::App; 7 - use bevy_butler::butler_plugin; 8 - use bevy_ecs::prelude::Component; 9 - use bevy_status_effects_macros::StatusEffect; 10 - 11 - #[butler_plugin] 12 - struct ButlerPlugin; 13 - 14 - #[derive(StatusEffect, Component, Debug, Eq, PartialEq, Default)] 15 - #[add_component(plugin = ButlerPlugin)] 16 - struct Derive; 17 - 18 - #[derive(StatusEffect, Component, Debug, Eq, PartialEq, Default)] 19 - #[add_component(plugin = ButlerPlugin)] 20 - struct DeriveRefresh; 21 - 22 - #[test] 23 - fn derive_refresh() { 24 - let mut app = App::new(); 25 - app.add_plugins(ButlerPlugin); 26 - app.update(); 27 - 28 - let target = app.world_mut().spawn_empty().id(); 29 - let first = app 30 - .world_mut() 31 - .spawn((DeriveRefresh, Effecting(target), EffectMode::Replace)) 32 - .id(); 33 - let second = app 34 - .world_mut() 35 - .spawn((DeriveRefresh, Effecting(target), EffectMode::Replace)) 36 - .id(); 37 - 38 - app.world_mut().flush(); 39 - 40 - assert_eq!(app.world().get::<DeriveRefresh>(first), None); 41 - assert_eq!( 42 - app.world().get::<DeriveRefresh>(second), 43 - Some(&DeriveRefresh) 44 - ); 45 - } 46 - }
-222
bevy_status_effects/src/lib.rs
··· 1 - #[cfg(feature = "bevy_butler")] 2 - pub mod bevy_butler; 3 - 4 1 pub mod relation; 5 2 pub mod timer; 6 3 ··· 110 107 } 111 108 } 112 109 } 113 - 114 - #[cfg(test)] 115 - mod tests { 116 - use super::*; 117 - use crate as bevy_status_effects; 118 - use bevy_status_effects_macros::StatusEffect; 119 - use bevy_time::{Timer, TimerMode}; 120 - use std::time::Duration; 121 - 122 - #[derive(StatusEffect, Component, Debug, Eq, PartialEq, Default)] 123 - struct MyEffect; 124 - 125 - #[test] 126 - fn stack() { 127 - let mut world = World::new(); 128 - world 129 - .register_component_hooks::<MyEffect>() 130 - .on_add(effect_refresh_hook::<MyEffect>); 131 - 132 - let target = world.spawn_empty().id(); 133 - let first = world.spawn((MyEffect, Effecting(target))).id(); 134 - let second = world.spawn((MyEffect, Effecting(target))).id(); 135 - 136 - world.flush(); 137 - 138 - assert_eq!(world.get::<MyEffect>(first), Some(&MyEffect)); 139 - assert_eq!(world.get::<MyEffect>(second), Some(&MyEffect)); 140 - } 141 - 142 - #[test] 143 - fn refresh() { 144 - let mut world = World::new(); 145 - world 146 - .register_component_hooks::<MyEffect>() 147 - .on_add(effect_refresh_hook::<MyEffect>); 148 - 149 - let target = world.spawn_empty().id(); 150 - let first = world 151 - .spawn((MyEffect, Effecting(target), EffectMode::Replace)) 152 - .id(); 153 - let second = world 154 - .spawn((MyEffect, Effecting(target), EffectMode::Replace)) 155 - .id(); 156 - 157 - world.flush(); 158 - 159 - assert_eq!(world.get::<MyEffect>(first), None); 160 - assert_eq!(world.get::<MyEffect>(second), Some(&MyEffect)); 161 - } 162 - 163 - #[test] 164 - fn mixed() { 165 - let mut world = World::new(); 166 - world 167 - .register_component_hooks::<MyEffect>() 168 - .on_add(effect_refresh_hook::<MyEffect>); 169 - 170 - let target = world.spawn_empty().id(); 171 - 172 - let stack_1 = world.spawn((MyEffect, Effecting(target))).id(); 173 - let stack_2 = world 174 - .spawn((MyEffect, Effecting(target), EffectMode::Stack)) 175 - .id(); 176 - 177 - let replace_1 = world 178 - .spawn((MyEffect, Effecting(target), EffectMode::Replace)) 179 - .id(); 180 - let replace_2 = world 181 - .spawn((MyEffect, Effecting(target), EffectMode::Replace)) 182 - .id(); 183 - 184 - world.flush(); 185 - 186 - assert_eq!(world.get::<MyEffect>(stack_1), Some(&MyEffect)); 187 - assert_eq!(world.get::<MyEffect>(stack_2), Some(&MyEffect)); 188 - 189 - assert_eq!(world.get::<MyEffect>(replace_1), None); 190 - assert_eq!(world.get::<MyEffect>(replace_2), Some(&MyEffect)); 191 - } 192 - 193 - #[test] 194 - fn timer_replace() { 195 - let mut world = World::new(); 196 - world 197 - .register_component_hooks::<MyEffect>() 198 - .on_add(effect_refresh_hook::<MyEffect>); 199 - 200 - let target = world.spawn_empty().id(); 201 - let second_lifetime = Lifetime::from_seconds(2.0).with_mode(TimerMergeMode::Replace); 202 - world.spawn(( 203 - MyEffect, 204 - Effecting(target), 205 - EffectMode::Replace, 206 - Lifetime::from_seconds(1.0).with_mode(TimerMergeMode::Replace), 207 - )); 208 - let second = world 209 - .spawn(( 210 - MyEffect, 211 - Effecting(target), 212 - EffectMode::Replace, 213 - second_lifetime.clone(), 214 - )) 215 - .id(); 216 - 217 - world.flush(); 218 - 219 - assert_eq!(world.get::<Lifetime>(second), Some(&second_lifetime)); 220 - } 221 - 222 - #[test] 223 - fn timer_inherit() { 224 - let mut world = World::new(); 225 - world 226 - .register_component_hooks::<MyEffect>() 227 - .on_add(effect_refresh_hook::<MyEffect>); 228 - 229 - let target = world.spawn_empty().id(); 230 - let first_delay = Delay::from_seconds(1.0).with_mode(TimerMergeMode::Inherit); 231 - 232 - world.spawn(( 233 - MyEffect, 234 - Effecting(target), 235 - EffectMode::Replace, 236 - first_delay.clone(), 237 - )); 238 - let second = world 239 - .spawn(( 240 - MyEffect, 241 - Effecting(target), 242 - EffectMode::Replace, 243 - Delay::from_seconds(2.0).with_mode(TimerMergeMode::Inherit), 244 - )) 245 - .id(); 246 - 247 - world.flush(); 248 - 249 - assert_eq!(world.get::<Delay>(second), Some(&first_delay)); 250 - } 251 - 252 - #[test] 253 - fn timer_fraction() { 254 - let mut world = World::new(); 255 - world 256 - .register_component_hooks::<MyEffect>() 257 - .on_add(effect_refresh_hook::<MyEffect>); 258 - 259 - let target = world.spawn_empty().id(); 260 - 261 - let mut first_timer = Timer::from_seconds(2.0, TimerMode::Once); 262 - first_timer.tick(Duration::from_secs_f32(1.0)); 263 - 264 - world.spawn(( 265 - MyEffect, 266 - Effecting(target), 267 - EffectMode::Replace, 268 - Delay { 269 - timer: first_timer, 270 - mode: TimerMergeMode::Fraction, 271 - }, 272 - )); 273 - let second = world 274 - .spawn(( 275 - MyEffect, 276 - Effecting(target), 277 - EffectMode::Replace, 278 - Delay::from_seconds(10.0).with_mode(TimerMergeMode::Fraction), 279 - )) 280 - .id(); 281 - 282 - world.flush(); 283 - 284 - let mut expected_timer = Timer::from_seconds(10.0, TimerMode::Repeating); 285 - expected_timer.tick(Duration::from_secs_f32(5.0)); 286 - 287 - assert_eq!( 288 - world.get::<Delay>(second), 289 - Some(&Delay { 290 - timer: expected_timer, 291 - mode: TimerMergeMode::Fraction, 292 - }) 293 - ); 294 - } 295 - 296 - #[test] 297 - fn timer_max() { 298 - let mut world = World::new(); 299 - world 300 - .register_component_hooks::<MyEffect>() 301 - .on_add(effect_refresh_hook::<MyEffect>); 302 - 303 - let target = world.spawn_empty().id(); 304 - let max = Delay::from_seconds(3.0).with_mode(TimerMergeMode::Max); 305 - 306 - world.spawn(( 307 - MyEffect, 308 - Effecting(target), 309 - EffectMode::Replace, 310 - Delay::from_seconds(1.0).with_mode(TimerMergeMode::Max), 311 - )); 312 - world.spawn(( 313 - MyEffect, 314 - Effecting(target), 315 - EffectMode::Replace, 316 - max.clone(), 317 - )); 318 - let third = world 319 - .spawn(( 320 - MyEffect, 321 - Effecting(target), 322 - EffectMode::Replace, 323 - Delay::from_seconds(2.0).with_mode(TimerMergeMode::Max), 324 - )) 325 - .id(); 326 - 327 - world.flush(); 328 - 329 - assert_eq!(world.get::<Delay>(third), Some(&max)); 330 - } 331 - }
-48
bevy_status_effects/src/timer.rs
··· 158 158 delay.timer.tick(time.delta()); 159 159 } 160 160 } 161 - 162 - #[cfg(test)] 163 - mod tests { 164 - use super::*; 165 - 166 - #[test] 167 - fn merge_replace() { 168 - let first = Lifetime::from_seconds(1.0).with_mode(TimerMergeMode::Replace); 169 - let second = Lifetime::from_seconds(2.0).with_mode(TimerMergeMode::Replace); 170 - let mut result = second.clone(); 171 - result.merge(&first); 172 - 173 - assert_eq!(result, second); 174 - } 175 - 176 - #[test] 177 - fn merge_inherit() { 178 - let first = Lifetime::from_seconds(1.0).with_mode(TimerMergeMode::Inherit); 179 - let second = Lifetime::from_seconds(2.0).with_mode(TimerMergeMode::Inherit); 180 - let mut result = second.clone(); 181 - result.merge(&first); 182 - 183 - assert_eq!(result, first); 184 - } 185 - 186 - #[test] 187 - fn merge_fraction() { 188 - let first = Lifetime::from_seconds(1.0).with_mode(TimerMergeMode::Fraction); 189 - let second = Lifetime::from_seconds(2.0).with_mode(TimerMergeMode::Fraction); 190 - let mut result = second.clone(); 191 - result.merge(&first); 192 - 193 - assert_eq!(result, second); 194 - } 195 - 196 - #[test] 197 - fn merge_max() { 198 - let first = Lifetime::from_seconds(1.0).with_mode(TimerMergeMode::Max); 199 - let mut second = Lifetime::from_seconds(3.0).with_mode(TimerMergeMode::Max); 200 - second.merge(&first); 201 - let third = Lifetime::from_seconds(2.0).with_mode(TimerMergeMode::Max); 202 - 203 - let mut result = third.clone(); 204 - result.merge(&second); 205 - 206 - assert_eq!(result, second); 207 - } 208 - }
+44
bevy_status_effects/tests/bevy_butler.rs
··· 1 + #![cfg(feature = "bevy_butler")] 2 + 3 + use bevy_app::App; 4 + use bevy_butler::butler_plugin; 5 + use bevy_ecs::prelude::Component; 6 + use bevy_status_effects::relation::Effecting; 7 + use bevy_status_effects::*; 8 + use bevy_status_effects_macros::StatusEffect; 9 + 10 + #[butler_plugin] 11 + struct ButlerPlugin; 12 + 13 + #[derive(StatusEffect, Component, Debug, Eq, PartialEq, Default)] 14 + #[add_component(plugin = ButlerPlugin)] 15 + struct Derive; 16 + 17 + #[derive(StatusEffect, Component, Debug, Eq, PartialEq, Default)] 18 + #[add_component(plugin = ButlerPlugin)] 19 + struct DeriveRefresh; 20 + 21 + #[test] 22 + fn derive_refresh() { 23 + let mut app = App::new(); 24 + app.add_plugins(ButlerPlugin); 25 + app.update(); 26 + 27 + let target = app.world_mut().spawn_empty().id(); 28 + let first = app 29 + .world_mut() 30 + .spawn((DeriveRefresh, Effecting(target), EffectMode::Replace)) 31 + .id(); 32 + let second = app 33 + .world_mut() 34 + .spawn((DeriveRefresh, Effecting(target), EffectMode::Replace)) 35 + .id(); 36 + 37 + app.world_mut().flush(); 38 + 39 + assert_eq!(app.world().get::<DeriveRefresh>(first), None); 40 + assert_eq!( 41 + app.world().get::<DeriveRefresh>(second), 42 + Some(&DeriveRefresh) 43 + ); 44 + }
+202
bevy_status_effects/tests/merge_mode.rs
··· 1 + use bevy_ecs::prelude::*; 2 + use bevy_status_effects::relation::Effecting; 3 + use bevy_status_effects::timer::{Delay, EffectTimer, Lifetime, TimerMergeMode}; 4 + use bevy_status_effects::*; 5 + use bevy_time::*; 6 + use std::time::Duration; 7 + 8 + #[derive(StatusEffect, Component, Debug, Eq, PartialEq, Default)] 9 + struct MyEffect; 10 + 11 + #[test] 12 + fn stack() { 13 + let mut world = World::new(); 14 + init_effect_hook::<MyEffect>(&mut world); 15 + 16 + let target = world.spawn_empty().id(); 17 + let first = world.spawn((MyEffect, Effecting(target))).id(); 18 + let second = world.spawn((MyEffect, Effecting(target))).id(); 19 + 20 + world.flush(); 21 + 22 + assert_eq!(world.get::<MyEffect>(first), Some(&MyEffect)); 23 + assert_eq!(world.get::<MyEffect>(second), Some(&MyEffect)); 24 + } 25 + 26 + #[test] 27 + fn refresh() { 28 + let mut world = World::new(); 29 + init_effect_hook::<MyEffect>(&mut world); 30 + 31 + let target = world.spawn_empty().id(); 32 + let first = world 33 + .spawn((MyEffect, Effecting(target), EffectMode::Replace)) 34 + .id(); 35 + let second = world 36 + .spawn((MyEffect, Effecting(target), EffectMode::Replace)) 37 + .id(); 38 + 39 + world.flush(); 40 + 41 + assert_eq!(world.get::<MyEffect>(first), None); 42 + assert_eq!(world.get::<MyEffect>(second), Some(&MyEffect)); 43 + } 44 + 45 + #[test] 46 + fn mixed() { 47 + let mut world = World::new(); 48 + init_effect_hook::<MyEffect>(&mut world); 49 + 50 + let target = world.spawn_empty().id(); 51 + 52 + let stack_1 = world.spawn((MyEffect, Effecting(target))).id(); 53 + let stack_2 = world 54 + .spawn((MyEffect, Effecting(target), EffectMode::Stack)) 55 + .id(); 56 + 57 + let replace_1 = world 58 + .spawn((MyEffect, Effecting(target), EffectMode::Replace)) 59 + .id(); 60 + let replace_2 = world 61 + .spawn((MyEffect, Effecting(target), EffectMode::Replace)) 62 + .id(); 63 + 64 + world.flush(); 65 + 66 + assert_eq!(world.get::<MyEffect>(stack_1), Some(&MyEffect)); 67 + assert_eq!(world.get::<MyEffect>(stack_2), Some(&MyEffect)); 68 + 69 + assert_eq!(world.get::<MyEffect>(replace_1), None); 70 + assert_eq!(world.get::<MyEffect>(replace_2), Some(&MyEffect)); 71 + } 72 + 73 + #[test] 74 + fn timer_replace() { 75 + let mut world = World::new(); 76 + init_effect_hook::<MyEffect>(&mut world); 77 + 78 + let target = world.spawn_empty().id(); 79 + let second_lifetime = Lifetime::from_seconds(2.0).with_mode(TimerMergeMode::Replace); 80 + world.spawn(( 81 + MyEffect, 82 + Effecting(target), 83 + EffectMode::Replace, 84 + Lifetime::from_seconds(1.0).with_mode(TimerMergeMode::Replace), 85 + )); 86 + let second = world 87 + .spawn(( 88 + MyEffect, 89 + Effecting(target), 90 + EffectMode::Replace, 91 + second_lifetime.clone(), 92 + )) 93 + .id(); 94 + 95 + world.flush(); 96 + 97 + assert_eq!(world.get::<Lifetime>(second), Some(&second_lifetime)); 98 + } 99 + 100 + #[test] 101 + fn timer_inherit() { 102 + let mut world = World::new(); 103 + init_effect_hook::<MyEffect>(&mut world); 104 + 105 + let target = world.spawn_empty().id(); 106 + let first_delay = Delay::from_seconds(1.0).with_mode(TimerMergeMode::Inherit); 107 + 108 + world.spawn(( 109 + MyEffect, 110 + Effecting(target), 111 + EffectMode::Replace, 112 + first_delay.clone(), 113 + )); 114 + let second = world 115 + .spawn(( 116 + MyEffect, 117 + Effecting(target), 118 + EffectMode::Replace, 119 + Delay::from_seconds(2.0).with_mode(TimerMergeMode::Inherit), 120 + )) 121 + .id(); 122 + 123 + world.flush(); 124 + 125 + assert_eq!(world.get::<Delay>(second), Some(&first_delay)); 126 + } 127 + 128 + #[test] 129 + fn timer_fraction() { 130 + let mut world = World::new(); 131 + init_effect_hook::<MyEffect>(&mut world); 132 + 133 + let target = world.spawn_empty().id(); 134 + 135 + let mut first_timer = Timer::from_seconds(2.0, TimerMode::Once); 136 + first_timer.tick(Duration::from_secs_f32(1.0)); 137 + 138 + world.spawn(( 139 + MyEffect, 140 + Effecting(target), 141 + EffectMode::Replace, 142 + Delay { 143 + timer: first_timer, 144 + mode: TimerMergeMode::Fraction, 145 + }, 146 + )); 147 + let second = world 148 + .spawn(( 149 + MyEffect, 150 + Effecting(target), 151 + EffectMode::Replace, 152 + Delay::from_seconds(10.0).with_mode(TimerMergeMode::Fraction), 153 + )) 154 + .id(); 155 + 156 + world.flush(); 157 + 158 + let mut expected_timer = Timer::from_seconds(10.0, TimerMode::Repeating); 159 + expected_timer.tick(Duration::from_secs_f32(5.0)); 160 + 161 + assert_eq!( 162 + world.get::<Delay>(second), 163 + Some(&Delay { 164 + timer: expected_timer, 165 + mode: TimerMergeMode::Fraction, 166 + }) 167 + ); 168 + } 169 + 170 + #[test] 171 + fn timer_max() { 172 + let mut world = World::new(); 173 + init_effect_hook::<MyEffect>(&mut world); 174 + 175 + let target = world.spawn_empty().id(); 176 + let max = Delay::from_seconds(3.0).with_mode(TimerMergeMode::Max); 177 + 178 + world.spawn(( 179 + MyEffect, 180 + Effecting(target), 181 + EffectMode::Replace, 182 + Delay::from_seconds(1.0).with_mode(TimerMergeMode::Max), 183 + )); 184 + world.spawn(( 185 + MyEffect, 186 + Effecting(target), 187 + EffectMode::Replace, 188 + max.clone(), 189 + )); 190 + let third = world 191 + .spawn(( 192 + MyEffect, 193 + Effecting(target), 194 + EffectMode::Replace, 195 + Delay::from_seconds(2.0).with_mode(TimerMergeMode::Max), 196 + )) 197 + .id(); 198 + 199 + world.flush(); 200 + 201 + assert_eq!(world.get::<Delay>(third), Some(&max)); 202 + }
+44
bevy_status_effects/tests/timer.rs
··· 1 + use bevy_status_effects::timer::{EffectTimer, Lifetime, TimerMergeMode}; 2 + 3 + #[test] 4 + fn merge_replace() { 5 + let first = Lifetime::from_seconds(1.0).with_mode(TimerMergeMode::Replace); 6 + let second = Lifetime::from_seconds(2.0).with_mode(TimerMergeMode::Replace); 7 + let mut result = second.clone(); 8 + result.merge(&first); 9 + 10 + assert_eq!(result, second); 11 + } 12 + 13 + #[test] 14 + fn merge_inherit() { 15 + let first = Lifetime::from_seconds(1.0).with_mode(TimerMergeMode::Inherit); 16 + let second = Lifetime::from_seconds(2.0).with_mode(TimerMergeMode::Inherit); 17 + let mut result = second.clone(); 18 + result.merge(&first); 19 + 20 + assert_eq!(result, first); 21 + } 22 + 23 + #[test] 24 + fn merge_fraction() { 25 + let first = Lifetime::from_seconds(1.0).with_mode(TimerMergeMode::Fraction); 26 + let second = Lifetime::from_seconds(2.0).with_mode(TimerMergeMode::Fraction); 27 + let mut result = second.clone(); 28 + result.merge(&first); 29 + 30 + assert_eq!(result, second); 31 + } 32 + 33 + #[test] 34 + fn merge_max() { 35 + let first = Lifetime::from_seconds(1.0).with_mode(TimerMergeMode::Max); 36 + let mut second = Lifetime::from_seconds(3.0).with_mode(TimerMergeMode::Max); 37 + second.merge(&first); 38 + let third = Lifetime::from_seconds(2.0).with_mode(TimerMergeMode::Max); 39 + 40 + let mut result = third.clone(); 41 + result.merge(&second); 42 + 43 + assert_eq!(result, second); 44 + }