aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2023-09-30 16:30:13 -0500
committermat <git@matdoes.dev>2023-09-30 16:30:13 -0500
commit1c97e2329050020270462721e29f21a5d80ec9fd (patch)
tree4fca502e6c8033f878ece85866052694127ccc76
parent2c8e1e7e85074051b77264d6c5a6b434e0ffe68e (diff)
downloadazalea-drasl-1c97e2329050020270462721e29f21a5d80ec9fd.tar.xz
improve ascend (stolen from baritone)
-rw-r--r--azalea/src/pathfinder/mod.rs6
-rw-r--r--azalea/src/pathfinder/moves/basic.rs55
-rw-r--r--azalea/src/pathfinder/moves/mod.rs5
3 files changed, 53 insertions, 13 deletions
diff --git a/azalea/src/pathfinder/mod.rs b/azalea/src/pathfinder/mod.rs
index cd8a3301..9ecc6093 100644
--- a/azalea/src/pathfinder/mod.rs
+++ b/azalea/src/pathfinder/mod.rs
@@ -1,3 +1,6 @@
+//! A pathfinding plugin to make bots navigate the world. A lot of this code is
+//! based on [Baritone](https://github.com/cabaletta/baritone).
+
mod astar;
pub mod costs;
pub mod goals;
@@ -144,7 +147,7 @@ fn goto_listener(
// we store the goal so it can be recalculated later if necessary
pathfinder.goal = Some(event.goal.clone());
- pathfinder.successors_fn = Some(event.successors_fn.clone());
+ pathfinder.successors_fn = Some(event.successors_fn);
pathfinder.is_calculating = true;
let start = if pathfinder.path.is_empty() {
@@ -419,6 +422,7 @@ fn tick_execute_path(
start: pathfinder.last_reached_node.expect(
"pathfinder.last_reached_node should always be present if there's a path",
),
+ physics,
look_at_events: &mut look_at_events,
sprint_events: &mut sprint_events,
walk_events: &mut walk_events,
diff --git a/azalea/src/pathfinder/moves/basic.rs b/azalea/src/pathfinder/moves/basic.rs
index 4219f1e7..af940dc2 100644
--- a/azalea/src/pathfinder/moves/basic.rs
+++ b/azalea/src/pathfinder/moves/basic.rs
@@ -1,6 +1,6 @@
use std::f32::consts::SQRT_2;
-use azalea_client::{SprintDirection, StartSprintEvent};
+use azalea_client::{SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection};
use azalea_core::{BlockPos, CardinalDirection};
use azalea_world::Instance;
@@ -88,7 +88,7 @@ fn ascend_move(world: &Instance, pos: BlockPos) -> Vec<Edge> {
target: pos + offset,
data: MoveData {
execute: &execute_ascend_move,
- is_reached: &default_is_reached,
+ is_reached: &ascend_is_reached,
},
},
cost,
@@ -99,24 +99,58 @@ fn ascend_move(world: &Instance, pos: BlockPos) -> Vec<Edge> {
fn execute_ascend_move(
ExecuteCtx {
entity,
+ position,
target,
+ start,
look_at_events,
- sprint_events,
+ walk_events,
jump_events,
+ physics,
..
}: ExecuteCtx,
) {
- let center = target.center();
+ let target_center = target.center();
+
look_at_events.send(LookAtEvent {
entity,
- position: center,
+ position: target_center,
});
- jump_events.send(JumpEvent { entity });
- sprint_events.send(StartSprintEvent {
+ walk_events.send(StartWalkEvent {
entity,
- direction: SprintDirection::Forward,
+ direction: WalkDirection::Forward,
});
+
+ // these checks are to make sure we don't fall if our velocity is too high in
+ // the wrong direction
+
+ let x_axis = (start.x - target.x).abs(); // either 0 or 1
+ let z_axis = (start.z - target.z).abs(); // either 0 or 1
+
+ let flat_distance_to_next = x_axis as f64 * (target_center.x - position.x)
+ + z_axis as f64 * (target_center.z - position.z);
+ let side_distance = z_axis as f64 * (target_center.x - position.x).abs()
+ + x_axis as f64 * (target_center.z - position.z).abs();
+
+ let lateral_motion = x_axis as f64 * physics.delta.z + z_axis as f64 * physics.delta.x;
+ if lateral_motion > 0.1 {
+ return;
+ }
+
+ if flat_distance_to_next > 1.2 || side_distance > 0.2 {
+ return;
+ }
+
+ jump_events.send(JumpEvent { entity });
}
+#[must_use]
+pub fn ascend_is_reached(
+ IsReachedCtx {
+ position, target, ..
+ }: IsReachedCtx,
+) -> bool {
+ BlockPos::from(position) == target || BlockPos::from(position) == target.down(1)
+}
+
fn descend_move(world: &Instance, pos: BlockPos) -> Vec<Edge> {
let mut edges = Vec::new();
for dir in CardinalDirection::iter() {
@@ -143,7 +177,7 @@ fn descend_move(world: &Instance, pos: BlockPos) -> Vec<Edge> {
target: new_position,
data: MoveData {
execute: &execute_descend_move,
- is_reached: &is_reached_descend_move,
+ is_reached: &descend_is_reached,
},
},
cost,
@@ -176,6 +210,7 @@ fn execute_descend_move(
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 {
+ // this basically just exists to avoid doing spins while we're falling
look_at_events.send(LookAtEvent {
entity,
position: dest_ahead.center(),
@@ -197,7 +232,7 @@ fn execute_descend_move(
}
}
#[must_use]
-pub fn is_reached_descend_move(
+pub fn descend_is_reached(
IsReachedCtx {
target,
start,
diff --git a/azalea/src/pathfinder/moves/mod.rs b/azalea/src/pathfinder/moves/mod.rs
index 9aa6b363..01df0929 100644
--- a/azalea/src/pathfinder/moves/mod.rs
+++ b/azalea/src/pathfinder/moves/mod.rs
@@ -98,6 +98,7 @@ pub struct ExecuteCtx<'w1, 'w2, 'w3, 'w4, 'a> {
/// The last node that we reached.
pub start: BlockPos,
pub position: Vec3,
+ pub physics: &'a azalea_entity::Physics,
pub look_at_events: &'a mut EventWriter<'w1, LookAtEvent>,
pub sprint_events: &'a mut EventWriter<'w2, StartSprintEvent>,
@@ -120,11 +121,11 @@ pub fn default_is_reached(
IsReachedCtx {
position,
target,
- physics,
+ // physics,
..
}: IsReachedCtx,
) -> bool {
- BlockPos::from(position) == target && physics.on_ground
+ BlockPos::from(position) == target
}
#[cfg(test)]