From b03d2942e1bef98e13acadde5cbb8856a3f8c74d Mon Sep 17 00:00:00 2001 From: mat Date: Thu, 19 Mar 2026 04:12:20 -0100 Subject: implement speed effect --- azalea-entity/src/plugin/effect_events.rs | 58 +++++++++++++++++++++++++++++++ azalea-entity/src/plugin/mod.rs | 4 +++ 2 files changed, 62 insertions(+) create mode 100644 azalea-entity/src/plugin/effect_events.rs (limited to 'azalea-entity/src/plugin') diff --git a/azalea-entity/src/plugin/effect_events.rs b/azalea-entity/src/plugin/effect_events.rs new file mode 100644 index 00000000..2d37c463 --- /dev/null +++ b/azalea-entity/src/plugin/effect_events.rs @@ -0,0 +1,58 @@ +use azalea_registry::builtin::MobEffect; +use bevy_ecs::{entity::Entity, event::EntityEvent, observer::On, system::Query}; +use tracing::warn; + +use crate::{ActiveEffects, Attributes, MobEffectData, effects::attribute_modifier_for_effect}; + +#[derive(EntityEvent)] +pub struct AddEffectEvent { + pub entity: Entity, + pub id: MobEffect, + pub data: MobEffectData, +} +pub fn handle_add_effect( + add_effect: On, + mut query: Query<(&mut ActiveEffects, &mut Attributes)>, +) { + let Ok((mut active_effects, mut attributes)) = query.get_mut(add_effect.entity) else { + warn!("got handle_add_effect for an entity without the required components"); + return; + }; + + active_effects.insert(add_effect.id, add_effect.data.clone()); + + if let Some((attribute, modifier)) = attribute_modifier_for_effect(add_effect.id) { + let modifier = modifier.create(add_effect.data.amplifier); + if let Some(attribute) = attributes.get_mut(attribute) { + attribute.insert(modifier); + } + } +} + +#[derive(EntityEvent)] +pub struct RemoveEffectsEvent { + pub entity: Entity, + pub effects: Vec, +} +pub fn handle_remove_effects( + remove_effects: On, + mut query: Query<(&mut ActiveEffects, &mut Attributes)>, +) { + let Ok((mut active_effects, mut attributes)) = query.get_mut(remove_effects.entity) else { + warn!("got handle_remove_effects for an entity without the required components"); + return; + }; + + for &effect in &remove_effects.effects { + active_effects.remove(effect); + + if let Some((attribute, modifier)) = attribute_modifier_for_effect(effect) { + // we're just trying to get the id of the modifier, so the amplifier passed here + // doesn't matter + let modifier = modifier.create(0); + if let Some(attribute) = attributes.get_mut(attribute) { + attribute.remove(&modifier.id); + } + } + } +} diff --git a/azalea-entity/src/plugin/mod.rs b/azalea-entity/src/plugin/mod.rs index 6035f674..4d97080f 100644 --- a/azalea-entity/src/plugin/mod.rs +++ b/azalea-entity/src/plugin/mod.rs @@ -1,4 +1,5 @@ mod components; +pub mod effect_events; pub mod indexing; use std::collections::HashSet; @@ -22,6 +23,7 @@ use crate::{ FluidOnEyes, LookDirection, Physics, Pose, Position, dimensions::{EntityDimensions, calculate_dimensions}, metadata::{self, Health, Player}, + plugin::effect_events::{handle_add_effect, handle_remove_effects}, }; /// A Bevy [`SystemSet`] for various types of entity updates. @@ -65,6 +67,8 @@ impl Plugin for EntityPlugin { ), ) .add_systems(GameTick, (update_in_loaded_chunk, update_fluid_on_eyes)) + .add_observer(handle_add_effect) + .add_observer(handle_remove_effects) .init_resource::(); } } -- cgit v1.2.3