diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2025-01-10 16:45:27 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-01-10 16:45:27 -0600 |
| commit | 0d16f01571ec8315f3979eae46981e559ade1cf9 (patch) | |
| tree | ea43c32a57b0e6a67579d75a134dfbc009d09781 /azalea-entity/src | |
| parent | 615d8f9d2ac56b3244d328587243301da253eafd (diff) | |
| download | azalea-drasl-0d16f01571ec8315f3979eae46981e559ade1cf9.tar.xz | |
Fluid physics (#199)
* start implementing fluid physics
* Initial implementation of fluid pushing
* different travel function in water
* bubble columns
* jumping in water
* cleanup
* change ultrawarm to be required
* fix for clippy
Diffstat (limited to 'azalea-entity/src')
| -rw-r--r-- | azalea-entity/src/attributes.rs | 1 | ||||
| -rwxr-xr-x | azalea-entity/src/dimensions.rs | 11 | ||||
| -rw-r--r-- | azalea-entity/src/lib.rs | 89 | ||||
| -rw-r--r-- | azalea-entity/src/mining.rs | 4 | ||||
| -rw-r--r-- | azalea-entity/src/plugin/mod.rs | 10 |
5 files changed, 82 insertions, 33 deletions
diff --git a/azalea-entity/src/attributes.rs b/azalea-entity/src/attributes.rs index 797ea43c..9af3bcaa 100644 --- a/azalea-entity/src/attributes.rs +++ b/azalea-entity/src/attributes.rs @@ -11,6 +11,7 @@ use thiserror::Error; pub struct Attributes { pub speed: AttributeInstance, pub attack_speed: AttributeInstance, + pub water_movement_efficiency: AttributeInstance, } #[derive(Clone, Debug)] diff --git a/azalea-entity/src/dimensions.rs b/azalea-entity/src/dimensions.rs index 5236b80f..3db7e304 100755 --- a/azalea-entity/src/dimensions.rs +++ b/azalea-entity/src/dimensions.rs @@ -7,17 +7,12 @@ pub struct EntityDimensions { } impl EntityDimensions { - pub fn make_bounding_box(&self, pos: Vec3) -> AABB { + pub fn make_bounding_box(&self, pos: &Vec3) -> AABB { let radius = (self.width / 2.0) as f64; let height = self.height as f64; AABB { - min_x: pos.x - radius, - min_y: pos.y, - min_z: pos.z - radius, - - max_x: pos.x + radius, - max_y: pos.y + height, - max_z: pos.z + radius, + min: Vec3::new(pos.x - radius, pos.y, pos.z - radius), + max: Vec3::new(pos.x + radius, pos.y + height, pos.z + radius), } } } diff --git a/azalea-entity/src/lib.rs b/azalea-entity/src/lib.rs index 95a2ed3c..1512bbd3 100644 --- a/azalea-entity/src/lib.rs +++ b/azalea-entity/src/lib.rs @@ -17,7 +17,7 @@ use std::{ }; pub use attributes::Attributes; -use azalea_block::BlockState; +use azalea_block::{fluid_state::FluidKind, BlockState}; use azalea_buf::AzBuf; use azalea_core::{ aabb::AABB, @@ -207,8 +207,8 @@ impl From<&LastSentPosition> for BlockPos { /// A component for entities that can jump. /// -/// If this is true, the entity will try to jump every tick. (It's equivalent to -/// the space key being held in vanilla.) +/// If this is true, the entity will try to jump every tick. It's equivalent to +/// the space key being held in vanilla. #[derive(Debug, Component, Copy, Clone, Deref, DerefMut, Default)] pub struct Jumping(bool); @@ -251,19 +251,33 @@ impl Eq for LookDirection {} #[derive(Debug, Component, Clone, Default)] pub struct Physics { /// How fast the entity is moving. + /// + /// Sometimes referred to as the delta movement. pub velocity: Vec3, + pub vec_delta_codec: VecDeltaCodec, + + /// The position of the entity before it moved this tick. + /// + /// This is set immediately before physics is done. + pub old_position: Vec3, - /// X acceleration. - pub xxa: f32, - /// Y acceleration. - pub yya: f32, - /// Z acceleration. - pub zza: f32, + /// The acceleration here is the force that will be attempted to be added to + /// the entity's velocity next tick. + /// + /// You should typically not set this yourself, since it's controlled by how + /// the entity is trying to move. + pub x_acceleration: f32, + pub y_acceleration: f32, + pub z_acceleration: f32, on_ground: bool, last_on_ground: bool, - pub vec_delta_codec: VecDeltaCodec, + /// The number of ticks until we jump again, if the jump key is being held. + /// + /// This must be 0 for us to be able to jump. Sets to 10 when we do a jump + /// and sets to 0 if we're not trying to jump. + pub no_jump_delay: u32, /// The width and height of the entity. pub dimensions: EntityDimensions, @@ -276,21 +290,35 @@ pub struct Physics { pub horizontal_collision: bool, // pub minor_horizontal_collision: bool, pub vertical_collision: bool, + + pub water_fluid_height: f64, + pub lava_fluid_height: f64, + pub was_touching_water: bool, + + // TODO: implement fall_distance + pub fall_distance: f32, + // TODO: implement remaining_fire_ticks + pub remaining_fire_ticks: i32, } impl Physics { pub fn new(dimensions: EntityDimensions, pos: Vec3) -> Self { Self { velocity: Vec3::default(), + vec_delta_codec: VecDeltaCodec::new(pos), + + old_position: pos, - xxa: 0., - yya: 0., - zza: 0., + x_acceleration: 0., + y_acceleration: 0., + z_acceleration: 0., on_ground: false, last_on_ground: false, - bounding_box: dimensions.make_bounding_box(pos), + no_jump_delay: 0, + + bounding_box: dimensions.make_bounding_box(&pos), dimensions, has_impulse: false, @@ -298,7 +326,12 @@ impl Physics { horizontal_collision: false, vertical_collision: false, - vec_delta_codec: VecDeltaCodec::new(pos), + water_fluid_height: 0., + lava_fluid_height: 0., + was_touching_water: false, + + fall_distance: 0., + remaining_fire_ticks: 0, } } @@ -321,6 +354,25 @@ impl Physics { pub fn set_last_on_ground(&mut self, last_on_ground: bool) { self.last_on_ground = last_on_ground; } + + pub fn reset_fall_distance(&mut self) { + self.fall_distance = 0.; + } + pub fn clear_fire(&mut self) { + self.remaining_fire_ticks = 0; + } + + pub fn is_in_water(&self) -> bool { + self.was_touching_water + } + pub fn is_in_lava(&self) -> bool { + // TODO: also check `!this.firstTick &&` + self.lava_fluid_height > 0. + } + + pub fn set_old_pos(&mut self, pos: &Position) { + self.old_position = **pos; + } } /// Marker component for entities that are dead. @@ -420,10 +472,11 @@ impl EntityBundle { // entities have different defaults speed: AttributeInstance::new(0.1), attack_speed: AttributeInstance::new(4.0), + water_movement_efficiency: AttributeInstance::new(0.0), }, jumping: Jumping(false), - fluid_on_eyes: FluidOnEyes(azalea_registry::Fluid::Empty), + fluid_on_eyes: FluidOnEyes(FluidKind::Empty), on_climbable: OnClimbable(false), } } @@ -444,10 +497,10 @@ pub struct PlayerBundle { pub struct LocalEntity; #[derive(Component, Clone, Debug, PartialEq, Deref, DerefMut)] -pub struct FluidOnEyes(azalea_registry::Fluid); +pub struct FluidOnEyes(FluidKind); impl FluidOnEyes { - pub fn new(fluid: azalea_registry::Fluid) -> Self { + pub fn new(fluid: FluidKind) -> Self { Self(fluid) } } diff --git a/azalea-entity/src/mining.rs b/azalea-entity/src/mining.rs index ee5c961b..cfa0012e 100644 --- a/azalea-entity/src/mining.rs +++ b/azalea-entity/src/mining.rs @@ -1,4 +1,4 @@ -use azalea_block::{Block, BlockBehavior}; +use azalea_block::{fluid_state::FluidKind, Block, BlockBehavior}; use azalea_core::tier::get_item_tier; use azalea_registry as registry; @@ -105,7 +105,7 @@ fn destroy_speed( base_destroy_speed *= multiplier; } - if registry::tags::fluids::WATER.contains(fluid_on_eyes) + if **fluid_on_eyes == FluidKind::Water && enchantments::get_enchant_level(registry::Enchantment::AquaAffinity, player_inventory) == 0 { diff --git a/azalea-entity/src/plugin/mod.rs b/azalea-entity/src/plugin/mod.rs index 92918c69..7624f0ba 100644 --- a/azalea-entity/src/plugin/mod.rs +++ b/azalea-entity/src/plugin/mod.rs @@ -3,7 +3,7 @@ mod relative_updates; use std::collections::HashSet; -use azalea_block::BlockState; +use azalea_block::{fluid_state::FluidKind, BlockState}; use azalea_core::position::{BlockPos, ChunkPos, Vec3}; use azalea_world::{InstanceContainer, InstanceName, MinecraftEntityId}; use bevy_app::{App, Plugin, PreUpdate, Update}; @@ -104,11 +104,11 @@ pub fn update_fluid_on_eyes( .read() .get_fluid_state(&eye_block_pos) .unwrap_or_default(); - let fluid_cutoff_y = eye_block_pos.y as f64 + (fluid_at_eye.amount as f64 / 16f64); + let fluid_cutoff_y = (eye_block_pos.y as f32 + fluid_at_eye.height()) as f64; if fluid_cutoff_y > adjusted_eye_y { - **fluid_on_eyes = fluid_at_eye.fluid; + **fluid_on_eyes = fluid_at_eye.kind; } else { - **fluid_on_eyes = azalea_registry::Fluid::Empty; + **fluid_on_eyes = FluidKind::Empty; } } } @@ -198,7 +198,7 @@ pub fn clamp_look_direction(mut query: Query<&mut LookDirection>) { /// Cached position in the world must be updated. pub fn update_bounding_box(mut query: Query<(&Position, &mut Physics), Changed<Position>>) { for (position, mut physics) in query.iter_mut() { - let bounding_box = physics.dimensions.make_bounding_box(**position); + let bounding_box = physics.dimensions.make_bounding_box(position); physics.bounding_box = bounding_box; } } |
