aboutsummaryrefslogtreecommitdiff
path: root/azalea-physics/src/travel.rs
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2025-08-14 20:40:13 -0500
committerGitHub <noreply@github.com>2025-08-14 20:40:13 -0500
commite74ed047dbaf3877db4a89a2d589e992abd0bb11 (patch)
tree0a728c8be167a1d59a5492ed9df666f41cf12e57 /azalea-physics/src/travel.rs
parent6695132ddb31780786c67b8b9ff5df8ab3891438 (diff)
downloadazalea-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.rs246
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 {