diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2025-08-14 20:40:13 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-14 20:40:13 -0500 |
| commit | e74ed047dbaf3877db4a89a2d589e992abd0bb11 (patch) | |
| tree | 0a728c8be167a1d59a5492ed9df666f41cf12e57 /azalea-physics/src/travel.rs | |
| parent | 6695132ddb31780786c67b8b9ff5df8ab3891438 (diff) | |
| download | azalea-drasl-e74ed047dbaf3877db4a89a2d589e992abd0bb11.tar.xz | |
Sneaking (#237)
* start implementing sneaking
* fix horizontal_collision being inverted and cleanup
* clippy
* change dimensions and eye height based on pose
* proper support for automatically crouching in certain cases
* fix anticheat issues
* add line to changelog and update a comment
Diffstat (limited to 'azalea-physics/src/travel.rs')
| -rw-r--r-- | azalea-physics/src/travel.rs | 246 |
1 files changed, 93 insertions, 153 deletions
diff --git a/azalea-physics/src/travel.rs b/azalea-physics/src/travel.rs index 80c289d9..1c473a45 100644 --- a/azalea-physics/src/travel.rs +++ b/azalea-physics/src/travel.rs @@ -4,20 +4,21 @@ use azalea_core::{ position::{BlockPos, Vec3}, }; use azalea_entity::{ - Attributes, HasClientLoaded, Jumping, LocalEntity, LookDirection, OnClimbable, Physics, Pose, - Position, metadata::Sprinting, move_relative, + Attributes, HasClientLoaded, Jumping, LocalEntity, LookDirection, OnClimbable, Physics, + PlayerAbilities, Pose, Position, metadata::Sprinting, move_relative, }; use azalea_world::{Instance, InstanceContainer, InstanceName}; use bevy_ecs::prelude::*; use crate::{ - HandleRelativeFrictionAndCalculateMovementOpts, collision::{ - MoverType, Shapes, + MoveCtx, MoverType, Shapes, entity_collisions::{CollidableEntityQuery, PhysicsQuery, get_entity_collisions}, move_colliding, + world_collisions::{get_block_and_liquid_collisions, get_block_collisions}, }, get_block_pos_below_that_affects_movement, handle_relative_friction_and_calculate_movement, + local_player::PhysicsState, }; /// Move the entity with the given acceleration while handling friction, @@ -27,15 +28,17 @@ pub fn travel( mut query: Query< ( Entity, - &mut Physics, - &mut LookDirection, - &mut Position, - Option<&Sprinting>, - Option<&Pose>, &Attributes, &InstanceName, &OnClimbable, &Jumping, + Option<&PhysicsState>, + Option<&Sprinting>, + Option<&Pose>, + Option<&PlayerAbilities>, + &mut Physics, + &mut LookDirection, + &mut Position, ), (With<LocalEntity>, With<HasClientLoaded>), >, @@ -45,15 +48,17 @@ pub fn travel( ) { for ( entity, - mut physics, - direction, - position, - sprinting, - pose, attributes, world_name, on_climbable, jumping, + physics_state, + sprinting, + pose, + abilities, + mut physics, + direction, + position, ) in &mut query { let Some(world_lock) = instance_container.get(world_name) else { @@ -65,92 +70,57 @@ pub fn travel( // TODO: elytras - if physics.is_in_water() || physics.is_in_lava() { + let mut ctx = MoveCtx { + mover_type: MoverType::Own, + world: &world, + position, + physics: &mut physics, + source_entity: entity, + physics_query: &physics_query, + collidable_entity_query: &collidable_entity_query, + physics_state, + attributes, + abilities, + direction: *direction, + sprinting, + on_climbable: *on_climbable, + pose: pose.copied(), + jumping: *jumping, + }; + + if ctx.physics.is_in_water() || ctx.physics.is_in_lava() { // minecraft also checks for `this.isAffectedByFluids() && // !this.canStandOnFluid(fluidAtBlock)` here but it doesn't matter // for players - travel_in_fluid( - &world, - entity, - &mut physics, - *direction, - position, - attributes, - sprinting, - on_climbable, - &physics_query, - &collidable_entity_query, - ); + travel_in_fluid(&mut ctx); } else { - travel_in_air( - &world, - entity, - &mut physics, - *direction, - position, - attributes, - sprinting, - *on_climbable, - pose, - *jumping, - &physics_query, - &collidable_entity_query, - ); + travel_in_air(&mut ctx); } } } /// The usual movement when we're not in water or using an elytra. -#[allow(clippy::too_many_arguments)] -fn travel_in_air( - world: &Instance, - entity: Entity, - physics: &mut Physics, - direction: LookDirection, - position: Mut<Position>, - attributes: &Attributes, - sprinting: Sprinting, - on_climbable: OnClimbable, - pose: Option<&Pose>, - jumping: Jumping, - physics_query: &PhysicsQuery, - collidable_entity_query: &CollidableEntityQuery, -) { +fn travel_in_air(ctx: &mut MoveCtx) { let gravity = get_effective_gravity(); - let block_pos_below = get_block_pos_below_that_affects_movement(*position); + let block_pos_below = get_block_pos_below_that_affects_movement(*ctx.position); - let block_state_below = world + let block_state_below = ctx + .world .chunks .get_block_state(block_pos_below) .unwrap_or(BlockState::AIR); let block_below: Box<dyn BlockTrait> = block_state_below.into(); let block_friction = block_below.behavior().friction; - let inertia = if physics.on_ground() { + let inertia = if ctx.physics.on_ground() { block_friction * 0.91 } else { 0.91 }; // this applies the current delta - let mut movement = handle_relative_friction_and_calculate_movement( - HandleRelativeFrictionAndCalculateMovementOpts { - block_friction, - world, - physics, - direction, - position, - attributes, - is_sprinting: *sprinting, - on_climbable, - pose: pose.copied(), - jumping, - entity, - physics_query, - collidable_entity_query, - }, - ); + let mut movement = handle_relative_friction_and_calculate_movement(ctx, block_friction); movement.y -= gravity; @@ -162,9 +132,9 @@ fn travel_in_air( // if should_discard_friction(self) { if false { - physics.velocity = movement; + ctx.physics.velocity = movement; } else { - physics.velocity = Vec3 { + ctx.physics.velocity = Vec3 { x: movement.x * inertia as f64, y: movement.y * 0.9800000190734863f64, z: movement.z * inertia as f64, @@ -172,116 +142,86 @@ 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, - physics_query: &PhysicsQuery, - collidable_entity_query: &CollidableEntityQuery, -) { - let moving_down = physics.velocity.y <= 0.; - let y = position.y; +fn travel_in_fluid(ctx: &mut MoveCtx) { + let moving_down = ctx.physics.velocity.y <= 0.; + let y = ctx.position.y; let gravity = get_effective_gravity(); let acceleration = Vec3::new( - physics.x_acceleration as f64, - physics.y_acceleration as f64, - physics.z_acceleration as f64, + ctx.physics.x_acceleration as f64, + ctx.physics.y_acceleration as f64, + ctx.physics.z_acceleration as f64, ); - if physics.was_touching_water { - let mut water_movement_speed = if *sprinting { 0.9 } else { 0.8 }; + if ctx.physics.was_touching_water { + let mut water_movement_speed = if *ctx.sprinting { 0.9 } else { 0.8 }; let mut speed = 0.02; - let mut water_efficiency_modifier = attributes.water_movement_efficiency.calculate() as f32; - if !physics.on_ground() { + let mut water_efficiency_modifier = + ctx.attributes.water_movement_efficiency.calculate() as f32; + if !ctx.physics.on_ground() { water_efficiency_modifier *= 0.5; } if water_efficiency_modifier > 0. { water_movement_speed += (0.54600006 - water_movement_speed) * water_efficiency_modifier; - speed += (attributes.speed.calculate() as f32 - speed) * water_efficiency_modifier; + speed += (ctx.attributes.movement_speed.calculate() as f32 - speed) + * water_efficiency_modifier; } // if (this.hasEffect(MobEffects.DOLPHINS_GRACE)) { // waterMovementSpeed = 0.96F; // } - move_relative(physics, direction, speed, acceleration); - move_colliding( - MoverType::Own, - physics.velocity, - world, - &mut position, - physics, - Some(entity), - physics_query, - collidable_entity_query, - ) - .expect("Entity should exist"); + move_relative(ctx.physics, ctx.direction, speed, acceleration); + move_colliding(ctx, ctx.physics.velocity).expect("Entity should exist"); - let mut new_velocity = physics.velocity; - if physics.horizontal_collision && **on_climbable { + let mut new_velocity = ctx.physics.velocity; + if ctx.physics.horizontal_collision && *ctx.on_climbable { // underwater ladders new_velocity.y = 0.2; } new_velocity.x *= water_movement_speed as f64; new_velocity.y *= 0.8; new_velocity.z *= water_movement_speed as f64; - physics.velocity = - get_fluid_falling_adjusted_movement(gravity, moving_down, new_velocity, sprinting); + ctx.physics.velocity = + get_fluid_falling_adjusted_movement(gravity, moving_down, new_velocity, ctx.sprinting); } else { - move_relative(physics, direction, 0.02, acceleration); - move_colliding( - MoverType::Own, - physics.velocity, - world, - &mut position, - physics, - Some(entity), - physics_query, - collidable_entity_query, - ) - .expect("Entity should exist"); + move_relative(ctx.physics, ctx.direction, 0.02, acceleration); + move_colliding(ctx, ctx.physics.velocity).expect("Entity should exist"); - if physics.lava_fluid_height <= fluid_jump_threshold() { - physics.velocity.x *= 0.5; - physics.velocity.y *= 0.8; - physics.velocity.z *= 0.5; + if ctx.physics.lava_fluid_height <= fluid_jump_threshold() { + ctx.physics.velocity.x *= 0.5; + ctx.physics.velocity.y *= 0.8; + ctx.physics.velocity.z *= 0.5; let new_velocity = get_fluid_falling_adjusted_movement( gravity, moving_down, - physics.velocity, - sprinting, + ctx.physics.velocity, + ctx.sprinting, ); - physics.velocity = new_velocity; + ctx.physics.velocity = new_velocity; } else { - physics.velocity *= 0.5; + ctx.physics.velocity *= 0.5; } if gravity != 0.0 { - physics.velocity.y -= gravity / 4.0; + ctx.physics.velocity.y -= gravity / 4.0; } } - let velocity = physics.velocity; - if physics.horizontal_collision + let velocity = ctx.physics.velocity; + if ctx.physics.horizontal_collision && is_free( - world, - entity, - physics_query, - collidable_entity_query, - physics, - physics.bounding_box, - velocity.up(0.6).down(position.y).up(y), + ctx.world, + ctx.source_entity, + ctx.physics_query, + ctx.collidable_entity_query, + ctx.physics, + ctx.physics.bounding_box, + velocity.up(0.6).down(ctx.position.y).up(y), ) { - physics.velocity.y = 0.3; + ctx.physics.velocity.y = 0.3; } } @@ -316,7 +256,7 @@ fn is_free( source_entity: Entity, physics_query: &PhysicsQuery, collidable_entity_query: &CollidableEntityQuery, - entity_physics: &mut Physics, + entity_physics: &Physics, bounding_box: AABB, delta: Vec3, ) -> bool { @@ -333,19 +273,19 @@ fn is_free( ) && !contains_any_liquid(world, bounding_box) } -fn no_collision( +pub fn no_collision( world: &Instance, source_entity: Option<Entity>, physics_query: &PhysicsQuery, collidable_entity_query: &CollidableEntityQuery, - entity_physics: &mut Physics, + entity_physics: &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) + get_block_and_liquid_collisions(world, aabb) } else { - crate::collision::world_collisions::get_block_collisions(world, aabb) + get_block_collisions(world, aabb) }; for collision in collisions { |
