···11-use crate::relation::{EffectedBy, Effecting};
22-use crate::timer::{Delay, EffectTimer, Lifetime};
33-use crate::{EffectMode, StatusEffect};
44-use bevy_ecs::component::HookContext;
55-use bevy_ecs::prelude::{Component, RelationshipTarget, World};
66-use bevy_ecs::world::DeferredWorld;
77-88-/// A system that registers the effect hook for a given type.
99-pub fn init_effect_hook<T: Component + StatusEffect>(world: &mut World) {
1010- world
1111- .register_component_hooks::<T>()
1212- .on_add(effect_refresh_hook::<T>);
1313-}
1414-1515-fn effect_refresh_hook<T: Component + StatusEffect>(
1616- mut world: DeferredWorld,
1717- context: HookContext,
1818-) {
1919- let Some(mode) = world.get::<EffectMode>(context.entity).copied() else {
2020- return;
2121- };
2222-2323- if mode == EffectMode::Stack {
2424- return;
2525- }
2626-2727- let Some(target) = world.get::<Effecting>(context.entity) else {
2828- return;
2929- };
3030-3131- let effected_by = match world.get::<EffectedBy>(target.0) {
3232- Some(e) => e.collection().clone(),
3333- None => return,
3434- };
3535-3636- let old = effected_by.iter().find_map(|entity| {
3737- // `EffectedBy` not updated until later.
3838- assert_ne!(*entity, context.entity);
3939-4040- let Some(other_mode) = world.get::<EffectMode>(*entity) else {
4141- return None;
4242- };
4343-4444- if mode != *other_mode {
4545- return None;
4646- }
4747-4848- world
4949- .get::<T>(*entity)
5050- .and_then(|effect| Some((*entity, effect)))
5151- });
5252-5353- if let Some((old_entity, _old_effect)) = old {
5454- match mode {
5555- EffectMode::Stack => return,
5656- EffectMode::Replace => world.commands().entity(old_entity).despawn(),
5757- }
5858-5959- if let Some(old_lifetime) = world.get::<Lifetime>(old_entity).cloned() {
6060- if let Some(mut lifetime) = world.get_mut::<Lifetime>(context.entity) {
6161- lifetime.merge(&old_lifetime)
6262- }
6363- }
6464-6565- if let Some(old_delay) = world.get::<Delay>(old_entity).cloned() {
6666- if let Some(mut delay) = world.get_mut::<Delay>(context.entity) {
6767- delay.merge(&old_delay)
6868- }
6969- }
7070- }
7171-}
+5-10
bevy_status_effects/src/lib.rs
src/lib.rs
···11//! Relationship-based status effects for bevy.
2233-mod hook;
33+mod command;
44mod relation;
55mod timer;
6677use bevy_app::{App, Plugin, PreUpdate};
88use bevy_ecs::prelude::*;
99use bevy_reflect::prelude::ReflectDefault;
1010-use bevy_reflect::{Reflect, reflect_trait};
1010+use bevy_reflect::{reflect_trait, Reflect};
11111212-pub use bevy_status_effects_macros::StatusEffect;
1313-pub use hook::*;
1212+pub use command::*;
1413pub use relation::*;
1514pub use timer::*;
1616-1717-#[doc(hidden)]
1818-pub use bevy_app::Startup as __Startup;
19152016pub struct StatusEffectPlugin;
2117···4137 /// Multiple of the same effect can exist at once.
4238 #[default]
4339 Stack,
4444- /// When an effect is spawned, any existing effects are replaced (despawned).
4040+ /// When an effect is added, any matching effects are removed.
4541 Replace,
4646- // Todo
4747- // Merge,
4242+ Merge,
4843}