aboutsummaryrefslogtreecommitdiff
path: root/azalea-entity/src
diff options
context:
space:
mode:
authorShayBox <shaybox@shaybox.com>2025-10-30 12:14:19 -0400
committerGitHub <noreply@github.com>2025-10-30 11:14:19 -0500
commit818f2d01d49e574946d1a704e1445156afc9c2fb (patch)
tree4190ce61994e7d1280cbcd6b43811fa9f6b03b09 /azalea-entity/src
parentc7cc381fae569f3dfc9f2abe86c2c38d59b68cf2 (diff)
downloadazalea-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.rs83
-rw-r--r--azalea-entity/src/lib.rs3
-rw-r--r--azalea-entity/src/mining.rs11
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,