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 std::f32::consts::SQRT_2;
use azalea_client::{SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection}; use azalea_client::{SprintDirection, WalkDirection};
use azalea_core::{ use azalea_core::{
direction::CardinalDirection, direction::CardinalDirection,
position::{BlockPos, Vec3}, position::{BlockPos, Vec3},
}; };
use crate::{ use crate::pathfinder::{astar, costs::*};
pathfinder::{astar, costs::*},
JumpEvent, LookAtEvent,
};
use super::{default_is_reached, Edge, ExecuteCtx, IsReachedCtx, MoveData, PathfinderCtx}; 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); ascend_move(edges, ctx, node);
descend_move(edges, ctx, node); descend_move(edges, ctx, node);
diagonal_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) { 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( fn execute_forward_move(mut ctx: ExecuteCtx) {
ExecuteCtx { let center = ctx.target.center();
entity, ctx.look_at(center);
target, ctx.sprint(SprintDirection::Forward);
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 ascend_move(edges: &mut Vec<Edge>, ctx: &PathfinderCtx, pos: BlockPos) { 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( fn execute_ascend_move(mut ctx: ExecuteCtx) {
ExecuteCtx { let ExecuteCtx {
entity,
position,
target, target,
start, start,
look_at_events, position,
walk_events,
jump_events,
physics, physics,
.. ..
}: ExecuteCtx, } = ctx;
) {
let target_center = target.center(); let target_center = target.center();
look_at_events.send(LookAtEvent { ctx.look_at(target_center);
entity, ctx.walk(WalkDirection::Forward);
position: target_center,
});
walk_events.send(StartWalkEvent {
entity,
direction: WalkDirection::Forward,
});
// these checks are to make sure we don't fall if our velocity is too high in // these checks are to make sure we don't fall if our velocity is too high in
// the wrong direction // the wrong direction
@ -133,7 +107,7 @@ fn execute_ascend_move(
} }
if BlockPos::from(position) == start { if BlockPos::from(position) == start {
jump_events.send(JumpEvent { entity }); ctx.jump();
} }
} }
#[must_use] #[must_use]
@ -187,19 +161,17 @@ fn descend_move(edges: &mut Vec<Edge>, ctx: &PathfinderCtx, pos: BlockPos) {
}) })
} }
} }
fn execute_descend_move( fn execute_descend_move(mut ctx: ExecuteCtx) {
ExecuteCtx { let ExecuteCtx {
entity,
target, target,
start, start,
look_at_events,
walk_events,
position, position,
.. ..
}: ExecuteCtx, } = ctx;
) {
let start_center = start.center(); 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();
@ -213,32 +185,16 @@ fn execute_descend_move(
if BlockPos::from(position) != target || horizontal_distance_from_target > 0.25 { if BlockPos::from(position) != target || horizontal_distance_from_target > 0.25 {
if horizontal_distance_from_start < 1.25 { 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 { ctx.look_at(dest_ahead);
entity, ctx.walk(WalkDirection::Forward);
position: dest_ahead,
});
walk_events.send(StartWalkEvent {
entity,
direction: WalkDirection::Forward,
});
} else { } else {
look_at_events.send(LookAtEvent { ctx.look_at(center);
entity, ctx.walk(WalkDirection::Forward);
position: center,
});
walk_events.send(StartWalkEvent {
entity,
direction: WalkDirection::Forward,
});
} }
} else { } else {
walk_events.send(StartWalkEvent { ctx.walk(WalkDirection::None);
entity,
direction: WalkDirection::None,
});
} }
} }
#[must_use] #[must_use]
pub fn descend_is_reached( pub fn descend_is_reached(
IsReachedCtx { IsReachedCtx {
@ -258,6 +214,58 @@ pub fn descend_is_reached(
&& (position.y - target.y as f64) < 0.5 && (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) { fn diagonal_move(edges: &mut Vec<Edge>, ctx: &PathfinderCtx, pos: BlockPos) {
for dir in CardinalDirection::iter() { for dir in CardinalDirection::iter() {
let right = dir.right(); let right = dir.right();
@ -296,23 +304,9 @@ fn diagonal_move(edges: &mut Vec<Edge>, ctx: &PathfinderCtx, pos: BlockPos) {
}) })
} }
} }
fn execute_diagonal_move( fn execute_diagonal_move(mut ctx: ExecuteCtx) {
ExecuteCtx { let target_center = ctx.target.center();
entity,
target,
look_at_events,
sprint_events,
..
}: ExecuteCtx,
) {
let target_center = target.center();
look_at_events.send(LookAtEvent { ctx.look_at(target_center);
entity, ctx.sprint(SprintDirection::Forward);
position: target_center,
});
sprint_events.send(StartSprintEvent {
entity,
direction: SprintDirection::Forward,
});
} }

View file

@ -11,7 +11,7 @@ use crate::{JumpEvent, LookAtEvent};
use super::astar; use super::astar;
use azalea_block::BlockState; use azalea_block::BlockState;
use azalea_client::{StartSprintEvent, StartWalkEvent}; use azalea_client::{SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection};
use azalea_core::{ use azalea_core::{
bitset::FixedBitSet, bitset::FixedBitSet,
position::{BlockPos, ChunkPos, ChunkSectionBlockPos, ChunkSectionPos, Vec3}, 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 walk_events: &'a mut EventWriter<'w3, StartWalkEvent>,
pub jump_events: &'a mut EventWriter<'w4, JumpEvent>, 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> { pub struct IsReachedCtx<'a> {
/// The node that we're trying to reach. /// The node that we're trying to reach.
pub target: BlockPos, 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 azalea_core::{direction::CardinalDirection, position::BlockPos};
use crate::{ use crate::pathfinder::{astar, costs::*};
pathfinder::{astar, costs::*},
JumpEvent, LookAtEvent,
};
use super::{default_is_reached, Edge, ExecuteCtx, IsReachedCtx, MoveData, PathfinderCtx}; 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( fn execute_parkour_move(mut ctx: ExecuteCtx) {
ExecuteCtx { let ExecuteCtx {
entity,
position, position,
target, target,
start, start,
look_at_events,
sprint_events,
walk_events,
jump_events,
.. ..
}: ExecuteCtx, } = ctx;
) {
let start_center = start.center(); let start_center = start.center();
let target_center = target.center(); let target_center = target.center();
look_at_events.send(LookAtEvent { ctx.look_at(target_center);
entity,
position: target_center,
});
let jump_distance = i32::max((target - start).x.abs(), (target - start).z.abs()); let jump_distance = i32::max((target - start).x.abs(), (target - start).z.abs());
if jump_distance >= 4 { if jump_distance >= 4 {
// 3 block gap // 3 block gap
sprint_events.send(StartSprintEvent { ctx.sprint(SprintDirection::Forward);
entity,
direction: SprintDirection::Forward,
});
} else { } else {
walk_events.send(StartWalkEvent { ctx.walk(WalkDirection::Forward);
entity,
direction: WalkDirection::Forward,
});
} }
let x_dir = (target.x - start.x).clamp(-1, 1); 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 if !is_at_start_block && is_at_jump_block && distance_from_start > required_distance_from_center
{ {
jump_events.send(JumpEvent { entity }); ctx.jump();
} }
} }