azalea/pathfinder/moves/
uncommon.rs1use azalea_core::direction::CardinalDirection;
4
5use crate::pathfinder::{
6 astar::{self, Edge},
7 costs::{CENTER_AFTER_FALL_COST, FALL_N_BLOCKS_COST, WALK_OFF_BLOCK_COST, WALK_ONE_BLOCK_COST},
8 moves::{
9 BARITONE_COMPAT, MoveData, MovesCtx,
10 basic::{descend_is_reached, execute_descend_move},
11 },
12 positions::RelBlockPos,
13};
14
15pub fn uncommon_move(ctx: &mut MovesCtx, node: RelBlockPos) {
16 if BARITONE_COMPAT {
17 return;
18 }
19 descend_forward_1_move(ctx, node);
20}
21
22pub fn descend_forward_1_move(ctx: &mut MovesCtx, pos: RelBlockPos) {
23 for dir in CardinalDirection::iter() {
24 let dir_delta = RelBlockPos::new(dir.x(), 0, dir.z());
25 let gap_horizontal_position = pos + dir_delta;
26 let new_horizontal_position = pos + dir_delta * 2;
27
28 let gap_fall_distance = ctx.world.fall_distance(gap_horizontal_position);
29 let fall_distance = ctx.world.fall_distance(new_horizontal_position);
30
31 if fall_distance == 0 || fall_distance > 3 || gap_fall_distance < fall_distance {
32 continue;
33 }
34
35 let new_position = new_horizontal_position.down(fall_distance as i32);
36
37 if !ctx.world.is_passable(new_horizontal_position) {
39 continue;
40 }
41 if !ctx.world.is_passable(gap_horizontal_position) {
42 continue;
43 }
44 if !ctx.world.is_standable(new_position) {
46 continue;
47 }
48
49 let cost = WALK_OFF_BLOCK_COST
50 + WALK_ONE_BLOCK_COST
51 + f32::max(
52 FALL_N_BLOCKS_COST
53 .get(fall_distance as usize)
54 .copied()
55 .unwrap_or(f32::INFINITY),
58 CENTER_AFTER_FALL_COST,
59 );
60
61 ctx.edges.push(Edge {
62 movement: astar::Movement {
63 target: new_position,
64 data: MoveData {
65 execute: &execute_descend_move,
66 is_reached: &descend_is_reached,
67 },
68 },
69 cost,
70 })
71 }
72}