diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2025-03-16 13:41:17 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-16 13:41:17 -0500 |
| commit | b0bd992adcff71ee294dd05060e00e652f62a7b2 (patch) | |
| tree | 0a36d8b37befbc75c8c65cc2c8779c3df66bd87b /azalea-physics/src/travel.rs | |
| parent | a95408cbcc05b5bd04a084b0a286b571069206f6 (diff) | |
| download | azalea-drasl-b0bd992adcff71ee294dd05060e00e652f62a7b2.tar.xz | |
Fluid physics fixes (#210)
* start fixing code related to fluid physics
* implement force_solid for blocks
* afk pool test
Diffstat (limited to 'azalea-physics/src/travel.rs')
| -rw-r--r-- | azalea-physics/src/travel.rs | 131 |
1 files changed, 117 insertions, 14 deletions
diff --git a/azalea-physics/src/travel.rs b/azalea-physics/src/travel.rs index e6145c18..0ee39f73 100644 --- a/azalea-physics/src/travel.rs +++ b/azalea-physics/src/travel.rs @@ -1,5 +1,8 @@ -use azalea_block::{Block, BlockState}; -use azalea_core::{aabb::AABB, position::Vec3}; +use azalea_block::{Block, BlockState, fluid_state::FluidState}; +use azalea_core::{ + aabb::AABB, + position::{BlockPos, Vec3}, +}; use azalea_entity::{ Attributes, InLoadedChunk, Jumping, LocalEntity, LookDirection, OnClimbable, Physics, Pose, Position, metadata::Sprinting, move_relative, @@ -9,7 +12,11 @@ use bevy_ecs::prelude::*; use crate::{ HandleRelativeFrictionAndCalculateMovementOpts, - collision::{MoverType, move_colliding}, + collision::{ + MoverType, Shapes, + entity_collisions::{CollidableEntityQuery, PhysicsQuery, get_entity_collisions}, + move_colliding, + }, get_block_pos_below_that_affects_movement, handle_relative_friction_and_calculate_movement, }; @@ -19,6 +26,7 @@ use crate::{ pub fn travel( mut query: Query< ( + Entity, &mut Physics, &mut LookDirection, &mut Position, @@ -32,8 +40,11 @@ pub fn travel( (With<LocalEntity>, With<InLoadedChunk>), >, instance_container: Res<InstanceContainer>, + physics_query: PhysicsQuery, + collidable_entity_query: CollidableEntityQuery, ) { for ( + entity, mut physics, direction, position, @@ -59,13 +70,16 @@ pub fn travel( // !this.canStandOnFluid(fluidAtBlock)` here but it doesn't matter // for players travel_in_fluid( + &world, + entity, &mut physics, &direction, position, attributes, sprinting, on_climbable, - &world, + &physics_query, + &collidable_entity_query, ); } else { travel_in_air( @@ -149,14 +163,18 @@ fn travel_in_air( } } +#[allow(clippy::too_many_arguments)] fn travel_in_fluid( + world: &Instance, + entity: Entity, physics: &mut Physics, direction: &LookDirection, mut position: Mut<Position>, attributes: &Attributes, sprinting: Sprinting, on_climbable: &OnClimbable, - world: &Instance, + physics_query: &PhysicsQuery, + collidable_entity_query: &CollidableEntityQuery, ) { let moving_down = physics.velocity.y <= 0.; let y = position.y; @@ -239,11 +257,13 @@ fn travel_in_fluid( let velocity = physics.velocity; if physics.horizontal_collision && is_free( - physics.bounding_box, world, - velocity.x, - velocity.y + 0.6 - position.y + y, - velocity.z, + entity, + physics_query, + collidable_entity_query, + physics, + physics.bounding_box, + velocity.up(0.6).down(position.y).up(y), ) { physics.velocity.y = 0.3; @@ -276,14 +296,97 @@ fn get_fluid_falling_adjusted_movement( } } -fn is_free(bounding_box: AABB, world: &Instance, x: f64, y: f64, z: f64) -> bool { - // let bounding_box = bounding_box.move_relative(Vec3::new(x, y, z)); +fn is_free( + world: &Instance, + source_entity: Entity, + physics_query: &PhysicsQuery, + collidable_entity_query: &CollidableEntityQuery, + entity_physics: &mut Physics, + bounding_box: AABB, + delta: Vec3, +) -> bool { + let bounding_box = bounding_box.move_relative(delta); + + no_collision( + world, + Some(source_entity), + physics_query, + collidable_entity_query, + entity_physics, + &bounding_box, + false, + ) && !contains_any_liquid(world, bounding_box) +} - let _ = (bounding_box, world, x, y, z); +fn no_collision( + world: &Instance, + source_entity: Option<Entity>, + physics_query: &PhysicsQuery, + collidable_entity_query: &CollidableEntityQuery, + entity_physics: &mut Physics, + aabb: &AABB, + include_liquid_collisions: bool, +) -> bool { + let collisions = if include_liquid_collisions { + crate::collision::world_collisions::get_block_and_liquid_collisions(world, aabb) + } else { + crate::collision::world_collisions::get_block_collisions(world, aabb) + }; - // TODO: implement this, see Entity.isFree + for collision in collisions { + if !collision.is_empty() { + return false; + } + } + + if !get_entity_collisions( + world, + aabb, + source_entity, + physics_query, + collidable_entity_query, + ) + .is_empty() + { + false + } else if source_entity.is_none() { + true + } else { + let collision = border_collision(entity_physics, aabb); + if let Some(collision) = collision { + // !Shapes.joinIsNotEmpty(collision, Shapes.create(aabb), BooleanOp.AND); + !Shapes::matches_anywhere(&collision.into(), &aabb.into(), |a, b| a && b) + } else { + true + } + } +} + +fn border_collision(_entity_physics: &Physics, _aabb: &AABB) -> Option<AABB> { + // TODO: implement world border, see CollisionGetter.borderCollision + + None +} + +fn contains_any_liquid(world: &Instance, bounding_box: AABB) -> bool { + let min = bounding_box.min.to_block_pos_floor(); + let max = bounding_box.max.to_block_pos_ceil(); + + for x in min.x..max.x { + for y in min.y..max.y { + for z in min.z..max.z { + let block_state = world + .chunks + .get_block_state(&BlockPos::new(x, y, z)) + .unwrap_or_default(); + if !FluidState::from(block_state).is_empty() { + return true; + } + } + } + } - true + false } fn get_effective_gravity() -> f64 { |
