diff --git a/azalea/src/pathfinder/astar.rs b/azalea/src/pathfinder/astar.rs index e5542531..505b09c0 100644 --- a/azalea/src/pathfinder/astar.rs +++ b/azalea/src/pathfinder/astar.rs @@ -122,7 +122,6 @@ where for node in best_paths.iter() { if node != start { - println!("chose best node {:?}", node); return *node; } } diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs index 1b35718e..de9c33da 100644 --- a/azalea/src/pathfinder/mod.rs +++ b/azalea/src/pathfinder/mod.rs @@ -370,12 +370,12 @@ fn tick_execute_path( position: **position, physics, }; - let on_ground_if_last = if i == pathfinder.path.len() - 1 { - physics.on_ground + let extra_strict_if_last = if i == pathfinder.path.len() - 1 { + physics.on_ground && BlockPos::from(position) == movement.target } else { true }; - if (movement.data.is_reached)(is_reached_ctx) && on_ground_if_last { + if (movement.data.is_reached)(is_reached_ctx) && extra_strict_if_last { pathfinder.path = pathfinder.path.split_off(i + 1); pathfinder.last_reached_node = Some(movement.target); pathfinder.last_node_reached_at = Some(Instant::now()); @@ -548,7 +548,6 @@ mod tests { use azalea_core::position::{BlockPos, ChunkPos, Vec3}; use azalea_world::{Chunk, ChunkStorage, PartialChunkStorage}; - use log::info; use super::{ goals::BlockPosGoal, @@ -589,7 +588,7 @@ mod tests { simulation.app.world.send_event(GotoEvent { entity: simulation.entity, goal: Arc::new(BlockPosGoal(end_pos)), - successors_fn: moves::basic::basic_move, + successors_fn: moves::default_move, }); simulation } @@ -627,9 +626,8 @@ mod tests { BlockPos::new(2, 72, 1), ], ); - for i in 0..30 { + for _ in 0..30 { simulation.tick(); - info!("-- tick #{i} --") } assert_eq!( BlockPos::from(simulation.position()), @@ -656,13 +654,78 @@ mod tests { BlockPos::new(5, 75, 0), ], ); - for i in 0..120 { + for _ in 0..120 { simulation.tick(); - info!("-- tick #{i} --") } assert_eq!( BlockPos::from(simulation.position()), BlockPos::new(5, 76, 0) ); } + + #[test] + fn test_parkour_2_block_gap() { + let mut partial_chunks = PartialChunkStorage::default(); + let mut simulation = setup_simulation( + &mut partial_chunks, + BlockPos::new(0, 71, 0), + BlockPos::new(0, 71, 3), + vec![BlockPos::new(0, 70, 0), BlockPos::new(0, 70, 3)], + ); + for _ in 0..40 { + simulation.tick(); + } + assert_eq!( + BlockPos::from(simulation.position()), + BlockPos::new(0, 71, 3) + ); + } + + #[test] + fn test_descend_and_parkour_2_block_gap() { + let mut partial_chunks = PartialChunkStorage::default(); + let mut simulation = setup_simulation( + &mut partial_chunks, + BlockPos::new(0, 71, 0), + BlockPos::new(3, 68, 3), + vec![ + BlockPos::new(0, 70, 0), + BlockPos::new(0, 69, 1), + BlockPos::new(0, 68, 2), + BlockPos::new(0, 67, 3), + BlockPos::new(0, 66, 4), + BlockPos::new(3, 66, 4), + ], + ); + for _ in 0..140 { + simulation.tick(); + } + assert_eq!( + BlockPos::from(simulation.position()), + BlockPos::new(3, 67, 4) + ); + } + + #[test] + fn test_quickly_descend() { + let mut partial_chunks = PartialChunkStorage::default(); + let mut simulation = setup_simulation( + &mut partial_chunks, + BlockPos::new(0, 71, 0), + BlockPos::new(0, 68, 3), + vec![ + BlockPos::new(0, 70, 0), + BlockPos::new(0, 69, 1), + BlockPos::new(0, 68, 2), + BlockPos::new(0, 67, 3), + ], + ); + for _ in 0..40 { + simulation.tick(); + } + assert_eq!( + BlockPos::from(simulation.position()), + BlockPos::new(0, 68, 3) + ); + } } diff --git a/azalea/src/pathfinder/moves/basic.rs b/azalea/src/pathfinder/moves/basic.rs index abd750b3..188eb3a6 100644 --- a/azalea/src/pathfinder/moves/basic.rs +++ b/azalea/src/pathfinder/moves/basic.rs @@ -1,7 +1,10 @@ use std::f32::consts::SQRT_2; use azalea_client::{SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection}; -use azalea_core::{direction::CardinalDirection, position::BlockPos}; +use azalea_core::{ + direction::CardinalDirection, + position::{BlockPos, Vec3}, +}; use azalea_world::Instance; use crate::{ @@ -140,7 +143,9 @@ fn execute_ascend_move( return; } - jump_events.send(JumpEvent { entity }); + if BlockPos::from(position) == start { + jump_events.send(JumpEvent { entity }); + } } #[must_use] pub fn ascend_is_reached( @@ -154,7 +159,8 @@ pub fn ascend_is_reached( fn descend_move(world: &Instance, pos: BlockPos) -> Vec { let mut edges = Vec::new(); for dir in CardinalDirection::iter() { - let new_horizontal_position = pos + BlockPos::new(dir.x(), 0, dir.z()); + let dir_delta = BlockPos::new(dir.x(), 0, dir.z()); + let new_horizontal_position = pos + dir_delta; let fall_distance = fall_distance(&new_horizontal_position, world); if fall_distance == 0 || fall_distance > 3 { continue; @@ -191,46 +197,48 @@ fn execute_descend_move( target, start, look_at_events, - sprint_events, + walk_events, position, .. }: ExecuteCtx, ) { + let start_center = start.center(); let center = target.center(); let horizontal_distance_from_target = (center - position).horizontal_distance_sqr().sqrt(); let horizontal_distance_from_start = (start.center() - position).horizontal_distance_sqr().sqrt(); - let dest_ahead = BlockPos::new( - start.x + (target.x - start.x) * 2, - target.y, - start.z + (target.z - start.z) * 2, + let dest_ahead = Vec3::new( + start_center.x + (center.x - start_center.x) * 1.5, + center.y, + start_center.z + (center.z - start_center.z) * 1.5, ); if BlockPos::from(position) != target || horizontal_distance_from_target > 0.25 { // if we're only falling one block then it's fine to try to overshoot - if horizontal_distance_from_start < 1.25 || start.y - target.y == 1 { + if horizontal_distance_from_start < 1.25 { // this basically just exists to avoid doing spins while we're falling look_at_events.send(LookAtEvent { entity, - position: dest_ahead.center(), + position: dest_ahead, }); - sprint_events.send(StartSprintEvent { + walk_events.send(StartWalkEvent { entity, - direction: SprintDirection::Forward, + direction: WalkDirection::Forward, }); } else { look_at_events.send(LookAtEvent { entity, position: center, }); - sprint_events.send(StartSprintEvent { + walk_events.send(StartWalkEvent { entity, - direction: SprintDirection::Forward, + direction: WalkDirection::Forward, }); } } } + #[must_use] pub fn descend_is_reached( IsReachedCtx {