aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2023-10-07 16:49:31 -0500
committermat <git@matdoes.dev>2023-10-07 16:49:31 -0500
commit78856fbefe900d23719cb049bd63840d56a093fd (patch)
treeeaa59d2bf6e26629dd22f756909072ad450364ea
parentad96ffa02ebebbbc49776538ada454681a624945 (diff)
downloadazalea-drasl-78856fbefe900d23719cb049bd63840d56a093fd.tar.xz
descend_forward_1_move move
-rw-r--r--azalea/src/pathfinder/moves/basic.rs168
-rw-r--r--azalea/src/pathfinder/moves/mod.rs37
-rw-r--r--azalea/src/pathfinder/moves/parkour.rs37
3 files changed, 127 insertions, 115 deletions
diff --git a/azalea/src/pathfinder/moves/basic.rs b/azalea/src/pathfinder/moves/basic.rs
index 71641716..531a2d00 100644
--- a/azalea/src/pathfinder/moves/basic.rs
+++ b/azalea/src/pathfinder/moves/basic.rs
@@ -1,15 +1,12 @@
use std::f32::consts::SQRT_2;
-use azalea_client::{SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection};
+use azalea_client::{SprintDirection, WalkDirection};
use azalea_core::{
direction::CardinalDirection,
position::{BlockPos, Vec3},
};
-use crate::{
- pathfinder::{astar, costs::*},
- JumpEvent, LookAtEvent,
-};
+use crate::pathfinder::{astar, costs::*};
use super::{default_is_reached, Edge, ExecuteCtx, IsReachedCtx, MoveData, PathfinderCtx};
@@ -18,6 +15,7 @@ pub fn basic_move(edges: &mut Vec<Edge>, ctx: &PathfinderCtx, node: BlockPos) {
ascend_move(edges, ctx, node);
descend_move(edges, ctx, node);
diagonal_move(edges, ctx, node);
+ descend_forward_1_move(edges, ctx, node);
}
fn forward_move(edges: &mut Vec<Edge>, ctx: &PathfinderCtx, pos: BlockPos) {
@@ -43,24 +41,10 @@ fn forward_move(edges: &mut Vec<Edge>, ctx: &PathfinderCtx, pos: BlockPos) {
}
}
-fn execute_forward_move(
- ExecuteCtx {
- entity,
- target,
- look_at_events,
- sprint_events,
- ..
- }: ExecuteCtx,
-) {
- let center = target.center();
- look_at_events.send(LookAtEvent {
- entity,
- position: center,
- });
- sprint_events.send(StartSprintEvent {
- entity,
- direction: SprintDirection::Forward,
- });
+fn execute_forward_move(mut ctx: ExecuteCtx) {
+ let center = ctx.target.center();
+ ctx.look_at(center);
+ ctx.sprint(SprintDirection::Forward);
}
fn ascend_move(edges: &mut Vec<Edge>, ctx: &PathfinderCtx, pos: BlockPos) {
@@ -88,29 +72,19 @@ fn ascend_move(edges: &mut Vec<Edge>, ctx: &PathfinderCtx, pos: BlockPos) {
})
}
}
-fn execute_ascend_move(
- ExecuteCtx {
- entity,
- position,
+fn execute_ascend_move(mut ctx: ExecuteCtx) {
+ let ExecuteCtx {
target,
start,
- look_at_events,
- walk_events,
- jump_events,
+ position,
physics,
..
- }: ExecuteCtx,
-) {
+ } = ctx;
+
let target_center = target.center();
- look_at_events.send(LookAtEvent {
- entity,
- position: target_center,
- });
- walk_events.send(StartWalkEvent {
- entity,
- direction: WalkDirection::Forward,
- });
+ ctx.look_at(target_center);
+ ctx.walk(WalkDirection::Forward);
// these checks are to make sure we don't fall if our velocity is too high in
// the wrong direction
@@ -133,7 +107,7 @@ fn execute_ascend_move(
}
if BlockPos::from(position) == start {
- jump_events.send(JumpEvent { entity });
+ ctx.jump();
}
}
#[must_use]
@@ -187,19 +161,17 @@ fn descend_move(edges: &mut Vec<Edge>, ctx: &PathfinderCtx, pos: BlockPos) {
})
}
}
-fn execute_descend_move(
- ExecuteCtx {
- entity,
+fn execute_descend_move(mut ctx: ExecuteCtx) {
+ let ExecuteCtx {
target,
start,
- look_at_events,
- walk_events,
position,
..
- }: ExecuteCtx,
-) {
+ } = ctx;
+
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();
@@ -213,32 +185,16 @@ fn execute_descend_move(
if BlockPos::from(position) != target || horizontal_distance_from_target > 0.25 {
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,
- });
- walk_events.send(StartWalkEvent {
- entity,
- direction: WalkDirection::Forward,
- });
+ ctx.look_at(dest_ahead);
+ ctx.walk(WalkDirection::Forward);
} else {
- look_at_events.send(LookAtEvent {
- entity,
- position: center,
- });
- walk_events.send(StartWalkEvent {
- entity,
- direction: WalkDirection::Forward,
- });
+ ctx.look_at(center);
+ ctx.walk(WalkDirection::Forward);
}
} else {
- walk_events.send(StartWalkEvent {
- entity,
- direction: WalkDirection::None,
- });
+ ctx.walk(WalkDirection::None);
}
}
-
#[must_use]
pub fn descend_is_reached(
IsReachedCtx {
@@ -258,6 +214,58 @@ pub fn descend_is_reached(
&& (position.y - target.y as f64) < 0.5
}
+fn descend_forward_1_move(edges: &mut Vec<Edge>, ctx: &PathfinderCtx, pos: BlockPos) {
+ for dir in CardinalDirection::iter() {
+ let dir_delta = BlockPos::new(dir.x(), 0, dir.z());
+ let gap_horizontal_position = pos + dir_delta;
+ let new_horizontal_position = pos + dir_delta * 2;
+
+ let gap_fall_distance = ctx.fall_distance(gap_horizontal_position);
+ let fall_distance = ctx.fall_distance(new_horizontal_position);
+
+ if fall_distance == 0 || fall_distance > 3 || gap_fall_distance < fall_distance {
+ continue;
+ }
+
+ let new_position = new_horizontal_position.down(fall_distance as i32);
+
+ // check whether 2 blocks vertically forward are passable
+ if !ctx.is_passable(new_horizontal_position) {
+ continue;
+ }
+ if !ctx.is_passable(gap_horizontal_position) {
+ continue;
+ }
+ // check whether we can stand on the target position
+ if !ctx.is_standable(new_position) {
+ continue;
+ }
+
+ let cost = WALK_OFF_BLOCK_COST
+ + WALK_ONE_BLOCK_COST
+ + f32::max(
+ FALL_N_BLOCKS_COST
+ .get(fall_distance as usize)
+ .copied()
+ // avoid panicking if we fall more than the size of FALL_N_BLOCKS_COST
+ // probably not possible but just in case
+ .unwrap_or(f32::MAX),
+ CENTER_AFTER_FALL_COST,
+ );
+
+ edges.push(Edge {
+ movement: astar::Movement {
+ target: new_position,
+ data: MoveData {
+ execute: &execute_descend_move,
+ is_reached: &descend_is_reached,
+ },
+ },
+ cost,
+ })
+ }
+}
+
fn diagonal_move(edges: &mut Vec<Edge>, ctx: &PathfinderCtx, pos: BlockPos) {
for dir in CardinalDirection::iter() {
let right = dir.right();
@@ -296,23 +304,9 @@ fn diagonal_move(edges: &mut Vec<Edge>, ctx: &PathfinderCtx, pos: BlockPos) {
})
}
}
-fn execute_diagonal_move(
- ExecuteCtx {
- entity,
- target,
- look_at_events,
- sprint_events,
- ..
- }: ExecuteCtx,
-) {
- let target_center = target.center();
+fn execute_diagonal_move(mut ctx: ExecuteCtx) {
+ let target_center = ctx.target.center();
- look_at_events.send(LookAtEvent {
- entity,
- position: target_center,
- });
- sprint_events.send(StartSprintEvent {
- entity,
- direction: SprintDirection::Forward,
- });
+ ctx.look_at(target_center);
+ ctx.sprint(SprintDirection::Forward);
}
diff --git a/azalea/src/pathfinder/moves/mod.rs b/azalea/src/pathfinder/moves/mod.rs
index c39590be..7feb8f40 100644
--- a/azalea/src/pathfinder/moves/mod.rs
+++ b/azalea/src/pathfinder/moves/mod.rs
@@ -11,7 +11,7 @@ use crate::{JumpEvent, LookAtEvent};
use super::astar;
use azalea_block::BlockState;
-use azalea_client::{StartSprintEvent, StartWalkEvent};
+use azalea_client::{SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection};
use azalea_core::{
bitset::FixedBitSet,
position::{BlockPos, ChunkPos, ChunkSectionBlockPos, ChunkSectionPos, Vec3},
@@ -313,6 +313,41 @@ pub struct ExecuteCtx<'w1, 'w2, 'w3, 'w4, 'a> {
pub walk_events: &'a mut EventWriter<'w3, StartWalkEvent>,
pub jump_events: &'a mut EventWriter<'w4, JumpEvent>,
}
+
+impl ExecuteCtx<'_, '_, '_, '_, '_> {
+ pub fn look_at(&mut self, position: Vec3) {
+ self.look_at_events.send(LookAtEvent {
+ entity: self.entity,
+ position: Vec3 {
+ x: position.x,
+ // look forward
+ y: self.position.up(1.53).y,
+ z: position.z,
+ },
+ });
+ }
+
+ pub fn sprint(&mut self, direction: SprintDirection) {
+ self.sprint_events.send(StartSprintEvent {
+ entity: self.entity,
+ direction,
+ });
+ }
+
+ pub fn walk(&mut self, direction: WalkDirection) {
+ self.walk_events.send(StartWalkEvent {
+ entity: self.entity,
+ direction,
+ });
+ }
+
+ pub fn jump(&mut self) {
+ self.jump_events.send(JumpEvent {
+ entity: self.entity,
+ });
+ }
+}
+
pub struct IsReachedCtx<'a> {
/// The node that we're trying to reach.
pub target: BlockPos,
diff --git a/azalea/src/pathfinder/moves/parkour.rs b/azalea/src/pathfinder/moves/parkour.rs
index e13581a0..e066fdb8 100644
--- a/azalea/src/pathfinder/moves/parkour.rs
+++ b/azalea/src/pathfinder/moves/parkour.rs
@@ -1,10 +1,7 @@
-use azalea_client::{SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection};
+use azalea_client::{SprintDirection, WalkDirection};
use azalea_core::{direction::CardinalDirection, position::BlockPos};
-use crate::{
- pathfinder::{astar, costs::*},
- JumpEvent, LookAtEvent,
-};
+use crate::pathfinder::{astar, costs::*};
use super::{default_is_reached, Edge, ExecuteCtx, IsReachedCtx, MoveData, PathfinderCtx};
@@ -109,39 +106,25 @@ fn parkour_forward_2_move(edges: &mut Vec<Edge>, ctx: &PathfinderCtx, pos: Block
}
}
-fn execute_parkour_move(
- ExecuteCtx {
- entity,
+fn execute_parkour_move(mut ctx: ExecuteCtx) {
+ let ExecuteCtx {
position,
target,
start,
- look_at_events,
- sprint_events,
- walk_events,
- jump_events,
..
- }: ExecuteCtx,
-) {
+ } = ctx;
+
let start_center = start.center();
let target_center = target.center();
- look_at_events.send(LookAtEvent {
- entity,
- position: target_center,
- });
+ ctx.look_at(target_center);
let jump_distance = i32::max((target - start).x.abs(), (target - start).z.abs());
if jump_distance >= 4 {
// 3 block gap
- sprint_events.send(StartSprintEvent {
- entity,
- direction: SprintDirection::Forward,
- });
+ ctx.sprint(SprintDirection::Forward);
} else {
- walk_events.send(StartWalkEvent {
- entity,
- direction: WalkDirection::Forward,
- });
+ ctx.walk(WalkDirection::Forward);
}
let x_dir = (target.x - start.x).clamp(-1, 1);
@@ -165,7 +148,7 @@ fn execute_parkour_move(
if !is_at_start_block && is_at_jump_block && distance_from_start > required_distance_from_center
{
- jump_events.send(JumpEvent { entity });
+ ctx.jump();
}
}