diff options
| author | ShayBox <shaybox@shaybox.com> | 2025-10-30 12:14:19 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-30 11:14:19 -0500 |
| commit | 818f2d01d49e574946d1a704e1445156afc9c2fb (patch) | |
| tree | 4190ce61994e7d1280cbcd6b43811fa9f6b03b09 /azalea-entity/src | |
| parent | c7cc381fae569f3dfc9f2abe86c2c38d59b68cf2 (diff) | |
| download | azalea-drasl-818f2d01d49e574946d1a704e1445156afc9c2fb.tar.xz | |
Add support for mob effects (#269)
* Add support for mob effects
* Remove Option
* MobEffectFlags
* jump_boost_power f32
Diffstat (limited to 'azalea-entity/src')
| -rw-r--r-- | azalea-entity/src/effects.rs | 83 | ||||
| -rw-r--r-- | azalea-entity/src/lib.rs | 3 | ||||
| -rw-r--r-- | azalea-entity/src/mining.rs | 11 |
3 files changed, 82 insertions, 15 deletions
diff --git a/azalea-entity/src/effects.rs b/azalea-entity/src/effects.rs index 9cc750e5..d905414d 100644 --- a/azalea-entity/src/effects.rs +++ b/azalea-entity/src/effects.rs @@ -1,21 +1,80 @@ -// TODO +use std::collections::HashMap; -// pub struct ActiveEffects(HashMap<azalea_registry::MobEffect, MobEffectData>); +use azalea_registry::MobEffect; +use bevy_ecs::component::Component; -/// Returns the level of the given effect, or `None` if the effect is not -/// active. The lowest level is 0. -pub fn get_effect(_effect: azalea_registry::MobEffect) -> Option<u32> { - // TODO - None +/// Data about an active mob effect that the client knows about. +#[derive(Clone, Debug, Default)] +pub struct MobEffectData { + pub amplifier: u32, + pub duration_ticks: u32, + pub ambient: bool, + pub show_particles: bool, + pub show_icon: bool, +} +impl MobEffectData { + pub fn new( + amplifier: u32, + duration_ticks: u32, + ambient: bool, + show_particles: bool, + show_icon: bool, + ) -> Self { + Self { + amplifier, + duration_ticks, + ambient, + show_particles, + show_icon, + } + } + + pub fn is_ambient(&self) -> bool { + self.ambient + } + pub fn should_show_particles(&self) -> bool { + self.show_particles + } + pub fn should_show_icon(&self) -> bool { + self.show_icon + } +} + +/// Component storing the active mob effects on an entity. +#[derive(Component, Clone, Debug, Default)] +pub struct ActiveEffects(pub HashMap<MobEffect, MobEffectData>); +impl ActiveEffects { + pub fn insert(&mut self, effect: MobEffect, data: MobEffectData) { + self.0.insert(effect, data); + } + + pub fn remove(&mut self, effect: MobEffect) -> Option<MobEffectData> { + self.0.remove(&effect) + } + + pub fn get_level(&self, effect: MobEffect) -> Option<u32> { + self.0.get(&effect).map(|data| data.amplifier) + } + + pub fn get(&self, effect: MobEffect) -> Option<&MobEffectData> { + self.0.get(&effect) + } +} + +/// Returns the level (amplifier) of the given effect, or `None` if the effect +/// is not active. The lowest level is 0. +pub fn get_effect(active_effects: &ActiveEffects, effect: MobEffect) -> Option<u32> { + active_effects.get_level(effect) } -pub fn get_dig_speed_amplifier() -> Option<u32> { +/// Returns the amplifier for dig speed (haste / conduit power), if present. +pub fn get_dig_speed_amplifier(active_effects: &ActiveEffects) -> Option<u32> { let effect_plus_one = u32::max( - get_effect(azalea_registry::MobEffect::Haste) - .map(|x| x + 1) + get_effect(active_effects, MobEffect::Haste) + .map(|level| level + 1) .unwrap_or_default(), - get_effect(azalea_registry::MobEffect::ConduitPower) - .map(|x| x + 1) + get_effect(active_effects, MobEffect::ConduitPower) + .map(|level| level + 1) .unwrap_or_default(), ); if effect_plus_one > 0 { diff --git a/azalea-entity/src/lib.rs b/azalea-entity/src/lib.rs index 4645e4ba..1f9e426e 100644 --- a/azalea-entity/src/lib.rs +++ b/azalea-entity/src/lib.rs @@ -31,6 +31,7 @@ use azalea_world::{ChunkStorage, InstanceName}; use bevy_ecs::{bundle::Bundle, component::Component}; pub use data::*; use derive_more::{Deref, DerefMut}; +pub use effects::{ActiveEffects, MobEffectData}; use plugin::indexing::EntityChunkPos; use uuid::Uuid; use vec_delta_codec::VecDeltaCodec; @@ -487,6 +488,7 @@ pub struct EntityBundle { pub crouching: Crouching, pub fluid_on_eyes: FluidOnEyes, pub on_climbable: OnClimbable, + pub active_effects: ActiveEffects, } impl EntityBundle { @@ -515,6 +517,7 @@ impl EntityBundle { crouching: Crouching(false), fluid_on_eyes: FluidOnEyes(FluidKind::Empty), on_climbable: OnClimbable(false), + active_effects: ActiveEffects::default(), } } } diff --git a/azalea-entity/src/mining.rs b/azalea-entity/src/mining.rs index cd526799..7c142020 100644 --- a/azalea-entity/src/mining.rs +++ b/azalea-entity/src/mining.rs @@ -2,7 +2,7 @@ use azalea_block::{BlockBehavior, BlockTrait}; use azalea_core::tier::get_item_tier; use azalea_registry as registry; -use crate::{FluidOnEyes, Physics, effects}; +use crate::{ActiveEffects, FluidOnEyes, Physics, effects}; /// How much progress is made towards mining the block per tick, as a /// percentage. @@ -20,6 +20,7 @@ pub fn get_mine_progress( player_inventory: &azalea_inventory::Menu, fluid_on_eyes: &FluidOnEyes, physics: &Physics, + active_effects: &ActiveEffects, ) -> f32 { let block_behavior: BlockBehavior = block.behavior(); @@ -39,6 +40,7 @@ pub fn get_mine_progress( player_inventory, fluid_on_eyes, physics, + active_effects, ); (base_destroy_speed / destroy_time) / divisor as f32 } @@ -82,6 +84,7 @@ fn destroy_speed( _player_inventory: &azalea_inventory::Menu, _fluid_on_eyes: &FluidOnEyes, physics: &Physics, + active_effects: &ActiveEffects, ) -> f32 { let mut base_destroy_speed = base_destroy_speed(block, tool); @@ -95,11 +98,13 @@ fn destroy_speed( // efficiency_level + 1) as f32; } // } - if let Some(dig_speed_amplifier) = effects::get_dig_speed_amplifier() { + if let Some(dig_speed_amplifier) = effects::get_dig_speed_amplifier(active_effects) { base_destroy_speed *= 1. + (dig_speed_amplifier + 1) as f32 * 0.2; } - if let Some(dig_slowdown) = effects::get_effect(registry::MobEffect::MiningFatigue) { + if let Some(dig_slowdown) = + effects::get_effect(active_effects, registry::MobEffect::MiningFatigue) + { let multiplier = match dig_slowdown { 0 => 0.3, 1 => 0.09, |
