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:
parent
befa33a879
commit
8b65d7c95e
3 changed files with 94 additions and 24 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Reference in a new issue