descend_forward_1_move move

This commit is contained in:
mat 2023-10-07 16:49:31 -05:00
parent ad96ffa02e
commit 78856fbefe
3 changed files with 127 additions and 115 deletions

View file

@ -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);
}

View file

@ -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,

View file

@ -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();
}
}