diff options
| author | mat <git@matdoes.dev> | 2026-01-18 10:15:41 +0800 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2026-01-18 11:18:36 +0900 |
| commit | 5c3ea8e1d97d92b4ea9c406bbb59f928ee0c6a66 (patch) | |
| tree | c7acff524da2229a0bc933ef1bf8a9c3e91d0bc6 /azalea/src/pathfinder/moves | |
| parent | 81e5a0200a4fe5438ab67c82600f063410d637c0 (diff) | |
| download | azalea-drasl-5c3ea8e1d97d92b4ea9c406bbb59f928ee0c6a66.tar.xz | |
don't fail parkour jumps that collide with ceiling blocks horizontally
Diffstat (limited to 'azalea/src/pathfinder/moves')
| -rw-r--r-- | azalea/src/pathfinder/moves/mod.rs | 21 | ||||
| -rw-r--r-- | azalea/src/pathfinder/moves/parkour.rs | 25 |
2 files changed, 44 insertions, 2 deletions
diff --git a/azalea/src/pathfinder/moves/mod.rs b/azalea/src/pathfinder/moves/mod.rs index 1ce541c8..d977c7bd 100644 --- a/azalea/src/pathfinder/moves/mod.rs +++ b/azalea/src/pathfinder/moves/mod.rs @@ -9,13 +9,13 @@ use std::{ use azalea_block::BlockState; use azalea_client::{ - SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection, + PhysicsState, SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection, inventory::SetSelectedHotbarSlotEvent, mining::StartMiningBlockEvent, }; use azalea_core::position::{BlockPos, Vec3}; use azalea_inventory::Menu; use azalea_world::World; -use bevy_ecs::{entity::Entity, message::MessageWriter, system::Commands}; +use bevy_ecs::{entity::Entity, message::MessageWriter, system::Commands, world::EntityWorldMut}; use parking_lot::RwLock; use tracing::debug; @@ -85,6 +85,10 @@ pub struct ExecuteCtx<'s, 'w1, 'w2, 'w3, 'w4, 'w5, 'w6, 'a> { } impl ExecuteCtx<'_, '_, '_, '_, '_, '_, '_, '_> { + pub fn on_tick_start(&mut self) { + self.set_sneaking(false); + } + pub fn look_at(&mut self, position: Vec3) { self.look_at_events.write(LookAtEvent { entity: self.entity, @@ -124,6 +128,19 @@ impl ExecuteCtx<'_, '_, '_, '_, '_, '_, '_, '_> { }); } + fn set_sneaking(&mut self, sneaking: bool) { + self.commands + .entity(self.entity) + .queue(move |mut entity: EntityWorldMut<'_>| { + if let Some(mut physics_state) = entity.get_mut::<PhysicsState>() { + physics_state.trying_to_crouch = sneaking; + } + }); + } + pub fn sneak(&mut self) { + self.set_sneaking(true); + } + pub fn jump_if_in_water(&mut self) { if self.physics.is_in_water() { self.jump(); diff --git a/azalea/src/pathfinder/moves/parkour.rs b/azalea/src/pathfinder/moves/parkour.rs index 4550ab95..d37c5751 100644 --- a/azalea/src/pathfinder/moves/parkour.rs +++ b/azalea/src/pathfinder/moves/parkour.rs @@ -1,5 +1,6 @@ use azalea_client::{SprintDirection, WalkDirection}; use azalea_core::{direction::CardinalDirection, position::BlockPos}; +use azalea_physics::collision::BlockWithShape; use tracing::trace; use super::{Edge, ExecuteCtx, IsReachedCtx, MoveData, MovesCtx}; @@ -232,6 +233,30 @@ fn execute_parkour_move(mut ctx: ExecuteCtx) { } else { ctx.look_at(target_center); trace!("looking at target_center"); + + // it's possible to hit our heads on a block when doing certain jumps (which + // resets our horizontal velocity), but we can avoid that by sneaking + if !ctx.physics.on_ground() && ctx.physics.velocity.y.abs() < 0.1 { + let should_sneak = { + let world = ctx.world.read(); + let pos_above = ctx.position.up(1.62 + 0.3); + let block_pos_above = BlockPos::from(pos_above); + let block_pos_above_plus_velocity = + BlockPos::from(pos_above + ctx.physics.velocity.with_y(0.) * 4.); + + let block_above = world.get_block_state(block_pos_above).unwrap_or_default(); + let block_above_plus_velocity = world + .get_block_state(block_pos_above_plus_velocity) + .unwrap_or_default(); + + // these checks are overly lenient but it doesn't matter much + !block_above.is_collision_shape_full() + && !block_above_plus_velocity.is_collision_shape_empty() + }; + if should_sneak { + ctx.sneak(); + } + } } if !is_at_start_block && is_at_jump_block && distance_from_start > required_distance_from_center |
