1
2
Fork 0
mirror of https://github.com/mat-1/azalea.git synced 2025-08-02 14:26:04 +00:00

pathfinder parkour tests and fix some parkour issues

This commit is contained in:
mat 2023-10-01 17:38:21 -05:00
parent befa33a879
commit 8b65d7c95e
3 changed files with 94 additions and 24 deletions

View file

@ -122,7 +122,6 @@ where
for node in best_paths.iter() { for node in best_paths.iter() {
if node != start { if node != start {
println!("chose best node {:?}", node);
return *node; return *node;
} }
} }

View file

@ -370,12 +370,12 @@ fn tick_execute_path(
position: **position, position: **position,
physics, physics,
}; };
let on_ground_if_last = if i == pathfinder.path.len() - 1 { let extra_strict_if_last = if i == pathfinder.path.len() - 1 {
physics.on_ground physics.on_ground && BlockPos::from(position) == movement.target
} else { } else {
true 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.path = pathfinder.path.split_off(i + 1);
pathfinder.last_reached_node = Some(movement.target); pathfinder.last_reached_node = Some(movement.target);
pathfinder.last_node_reached_at = Some(Instant::now()); pathfinder.last_node_reached_at = Some(Instant::now());
@ -548,7 +548,6 @@ mod tests {
use azalea_core::position::{BlockPos, ChunkPos, Vec3}; use azalea_core::position::{BlockPos, ChunkPos, Vec3};
use azalea_world::{Chunk, ChunkStorage, PartialChunkStorage}; use azalea_world::{Chunk, ChunkStorage, PartialChunkStorage};
use log::info;
use super::{ use super::{
goals::BlockPosGoal, goals::BlockPosGoal,
@ -589,7 +588,7 @@ mod tests {
simulation.app.world.send_event(GotoEvent { simulation.app.world.send_event(GotoEvent {
entity: simulation.entity, entity: simulation.entity,
goal: Arc::new(BlockPosGoal(end_pos)), goal: Arc::new(BlockPosGoal(end_pos)),
successors_fn: moves::basic::basic_move, successors_fn: moves::default_move,
}); });
simulation simulation
} }
@ -627,9 +626,8 @@ mod tests {
BlockPos::new(2, 72, 1), BlockPos::new(2, 72, 1),
], ],
); );
for i in 0..30 { for _ in 0..30 {
simulation.tick(); simulation.tick();
info!("-- tick #{i} --")
} }
assert_eq!( assert_eq!(
BlockPos::from(simulation.position()), BlockPos::from(simulation.position()),
@ -656,13 +654,78 @@ mod tests {
BlockPos::new(5, 75, 0), BlockPos::new(5, 75, 0),
], ],
); );
for i in 0..120 { for _ in 0..120 {
simulation.tick(); simulation.tick();
info!("-- tick #{i} --")
} }
assert_eq!( assert_eq!(
BlockPos::from(simulation.position()), BlockPos::from(simulation.position()),
BlockPos::new(5, 76, 0) 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)
);
}
} }

View file

@ -1,7 +1,10 @@
use std::f32::consts::SQRT_2; use std::f32::consts::SQRT_2;
use azalea_client::{SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection}; 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 azalea_world::Instance;
use crate::{ use crate::{
@ -140,7 +143,9 @@ fn execute_ascend_move(
return; return;
} }
jump_events.send(JumpEvent { entity }); if BlockPos::from(position) == start {
jump_events.send(JumpEvent { entity });
}
} }
#[must_use] #[must_use]
pub fn ascend_is_reached( pub fn ascend_is_reached(
@ -154,7 +159,8 @@ pub fn ascend_is_reached(
fn descend_move(world: &Instance, pos: BlockPos) -> Vec<Edge> { fn descend_move(world: &Instance, pos: BlockPos) -> Vec<Edge> {
let mut edges = Vec::new(); let mut edges = Vec::new();
for dir in CardinalDirection::iter() { 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); let fall_distance = fall_distance(&new_horizontal_position, world);
if fall_distance == 0 || fall_distance > 3 { if fall_distance == 0 || fall_distance > 3 {
continue; continue;
@ -191,46 +197,48 @@ fn execute_descend_move(
target, target,
start, start,
look_at_events, look_at_events,
sprint_events, walk_events,
position, position,
.. ..
}: ExecuteCtx, }: ExecuteCtx,
) { ) {
let start_center = start.center();
let center = target.center(); let center = target.center();
let horizontal_distance_from_target = (center - position).horizontal_distance_sqr().sqrt(); let horizontal_distance_from_target = (center - position).horizontal_distance_sqr().sqrt();
let horizontal_distance_from_start = let horizontal_distance_from_start =
(start.center() - position).horizontal_distance_sqr().sqrt(); (start.center() - position).horizontal_distance_sqr().sqrt();
let dest_ahead = BlockPos::new( let dest_ahead = Vec3::new(
start.x + (target.x - start.x) * 2, start_center.x + (center.x - start_center.x) * 1.5,
target.y, center.y,
start.z + (target.z - start.z) * 2, start_center.z + (center.z - start_center.z) * 1.5,
); );
if BlockPos::from(position) != target || horizontal_distance_from_target > 0.25 { 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 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 // this basically just exists to avoid doing spins while we're falling
look_at_events.send(LookAtEvent { look_at_events.send(LookAtEvent {
entity, entity,
position: dest_ahead.center(), position: dest_ahead,
}); });
sprint_events.send(StartSprintEvent { walk_events.send(StartWalkEvent {
entity, entity,
direction: SprintDirection::Forward, direction: WalkDirection::Forward,
}); });
} else { } else {
look_at_events.send(LookAtEvent { look_at_events.send(LookAtEvent {
entity, entity,
position: center, position: center,
}); });
sprint_events.send(StartSprintEvent { walk_events.send(StartWalkEvent {
entity, entity,
direction: SprintDirection::Forward, direction: WalkDirection::Forward,
}); });
} }
} }
} }
#[must_use] #[must_use]
pub fn descend_is_reached( pub fn descend_is_reached(
IsReachedCtx { IsReachedCtx {