diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2023-12-15 11:26:40 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-15 11:26:40 -0600 |
| commit | a707e2eb82b74994a16083b31fa4576332cf1995 (patch) | |
| tree | db6c2ac94dd73590befd68a9b1b0ef960410b0df /azalea/src/pathfinder/moves/basic.rs | |
| parent | 59e140ddd655c7dc6e35109b91286118c51bcc06 (diff) | |
| download | azalea-drasl-a707e2eb82b74994a16083b31fa4576332cf1995.tar.xz | |
Add mining to the pathfinder (#122)
* basic pathfinder mining poc
* mining descending and autotool
* pathfinder mining descending
* pathfinder fixes
* allow disabling pathfinder miner and other fixes
* small optimization to avoid chunk vec iter lookup sometimes
* seeded rng in pathfinder bench
* consistently use f32::INFINITY
this brings performance much closer to how it was before
* astar heuristic optimization from baritone
* add downward_move
* fix downward move execute
* avoid liquids and falling blocks when mining
* fix COST_HEURISTIC
* fix to not path through flowing liquids
* only reset pathfinder timeout while mining if the block is close enough
* cache mining costs of block positions
* fix mine_while_at_start and move PathfinderDebugParticles to its own module
* add ReachBlockPosGoal
in other news: azalea's sin/cos functions were broken this whole time and i never noticed
* clippy and add things that i accidentally didn't commit
* improve wording on doc for azalea::pathfinder
Diffstat (limited to 'azalea/src/pathfinder/moves/basic.rs')
| -rw-r--r-- | azalea/src/pathfinder/moves/basic.rs | 141 |
1 files changed, 124 insertions, 17 deletions
diff --git a/azalea/src/pathfinder/moves/basic.rs b/azalea/src/pathfinder/moves/basic.rs index 957e24c6..54a6dc6a 100644 --- a/azalea/src/pathfinder/moves/basic.rs +++ b/azalea/src/pathfinder/moves/basic.rs @@ -16,17 +16,20 @@ pub fn basic_move(ctx: &mut PathfinderCtx, node: BlockPos) { descend_move(ctx, node); diagonal_move(ctx, node); descend_forward_1_move(ctx, node); + downward_move(ctx, node); } fn forward_move(ctx: &mut PathfinderCtx, pos: BlockPos) { for dir in CardinalDirection::iter() { let offset = BlockPos::new(dir.x(), 0, dir.z()); - if !ctx.world.is_standable(pos + offset) { + let mut cost = SPRINT_ONE_BLOCK_COST; + + let break_cost = ctx.world.cost_for_standing(pos + offset, ctx.mining_cache); + if break_cost == f32::INFINITY { continue; } - - let cost = SPRINT_ONE_BLOCK_COST; + cost += break_cost; ctx.edges.push(Edge { movement: astar::Movement { @@ -43,6 +46,14 @@ fn forward_move(ctx: &mut PathfinderCtx, pos: BlockPos) { fn execute_forward_move(mut ctx: ExecuteCtx) { let center = ctx.target.center(); + + if ctx.mine_while_at_start(ctx.target.up(1)) { + return; + } + if ctx.mine_while_at_start(ctx.target) { + return; + } + ctx.look_at(center); ctx.sprint(SprintDirection::Forward); } @@ -51,14 +62,22 @@ fn ascend_move(ctx: &mut PathfinderCtx, pos: BlockPos) { for dir in CardinalDirection::iter() { let offset = BlockPos::new(dir.x(), 1, dir.z()); - if !ctx.world.is_block_passable(pos.up(2)) { + let break_cost_1 = ctx + .world + .cost_for_breaking_block(pos.up(2), ctx.mining_cache); + if break_cost_1 == f32::INFINITY { continue; } - if !ctx.world.is_standable(pos + offset) { + let break_cost_2 = ctx.world.cost_for_standing(pos + offset, ctx.mining_cache); + if break_cost_2 == f32::INFINITY { continue; } - let cost = SPRINT_ONE_BLOCK_COST + JUMP_PENALTY + *JUMP_ONE_BLOCK_COST; + let cost = SPRINT_ONE_BLOCK_COST + + JUMP_PENALTY + + *JUMP_ONE_BLOCK_COST + + break_cost_1 + + break_cost_2; ctx.edges.push(Edge { movement: astar::Movement { @@ -81,6 +100,16 @@ fn execute_ascend_move(mut ctx: ExecuteCtx) { .. } = ctx; + if ctx.mine_while_at_start(start.up(2)) { + return; + } + if ctx.mine_while_at_start(target) { + return; + } + if ctx.mine_while_at_start(target.up(1)) { + return; + } + let target_center = target.center(); ctx.look_at(target_center); @@ -123,19 +152,39 @@ fn descend_move(ctx: &mut PathfinderCtx, pos: BlockPos) { for dir in CardinalDirection::iter() { let dir_delta = BlockPos::new(dir.x(), 0, dir.z()); let new_horizontal_position = pos + dir_delta; - let fall_distance = ctx.world.fall_distance(new_horizontal_position); - if fall_distance == 0 || fall_distance > 3 { + + let break_cost_1 = ctx + .world + .cost_for_passing(new_horizontal_position, ctx.mining_cache); + if break_cost_1 == f32::INFINITY { continue; } - let new_position = new_horizontal_position.down(fall_distance as i32); - // check whether 3 blocks vertically forward are passable - if !ctx.world.is_passable(new_horizontal_position) { + let mut fall_distance = ctx.world.fall_distance(new_horizontal_position); + if fall_distance > 3 { continue; } - // check whether we can stand on the target position - if !ctx.world.is_standable(new_position) { - continue; + + if fall_distance == 0 { + // if the fall distance is 0, set it to 1 so we try mining + fall_distance = 1 + } + + let new_position = new_horizontal_position.down(fall_distance as i32); + + // only mine if we're descending 1 block + let break_cost_2; + if fall_distance == 1 { + break_cost_2 = ctx.world.cost_for_standing(new_position, ctx.mining_cache); + if break_cost_2 == f32::INFINITY { + continue; + } + } else { + // check whether we can stand on the target position + if !ctx.world.is_standable(new_position) { + continue; + } + break_cost_2 = 0.; } let cost = WALK_OFF_BLOCK_COST @@ -145,9 +194,11 @@ fn descend_move(ctx: &mut PathfinderCtx, pos: BlockPos) { .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), + .unwrap_or(f32::INFINITY), CENTER_AFTER_FALL_COST, - ); + ) + + break_cost_1 + + break_cost_2; ctx.edges.push(Edge { movement: astar::Movement { @@ -169,6 +220,12 @@ fn execute_descend_move(mut ctx: ExecuteCtx) { .. } = ctx; + for i in (0..=(start.y - target.y + 1)).rev() { + if ctx.mine_while_at_start(target.up(i)) { + return; + } + } + let start_center = start.center(); let center = target.center(); @@ -249,7 +306,7 @@ fn descend_forward_1_move(ctx: &mut PathfinderCtx, pos: BlockPos) { .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), + .unwrap_or(f32::INFINITY), CENTER_AFTER_FALL_COST, ); @@ -310,3 +367,53 @@ fn execute_diagonal_move(mut ctx: ExecuteCtx) { ctx.look_at(target_center); ctx.sprint(SprintDirection::Forward); } + +/// Go directly down, usually by mining. +fn downward_move(ctx: &mut PathfinderCtx, pos: BlockPos) { + // make sure we land on a solid block after breaking the one below us + if !ctx.world.is_block_solid(pos.down(2)) { + return; + } + + let break_cost = ctx + .world + .cost_for_breaking_block(pos.down(1), ctx.mining_cache); + if break_cost == f32::INFINITY { + return; + } + + let cost = FALL_N_BLOCKS_COST[1] + break_cost; + + ctx.edges.push(Edge { + movement: astar::Movement { + target: pos.down(1), + data: MoveData { + execute: &execute_downward_move, + is_reached: &default_is_reached, + }, + }, + cost, + }) +} +fn execute_downward_move(mut ctx: ExecuteCtx) { + let ExecuteCtx { + target, position, .. + } = ctx; + + let target_center = target.center(); + + let horizontal_distance_from_target = + (target_center - position).horizontal_distance_sqr().sqrt(); + + if horizontal_distance_from_target > 0.25 { + ctx.look_at(target_center); + ctx.walk(WalkDirection::Forward); + } else if ctx.mine_while_at_start(target) { + ctx.walk(WalkDirection::None); + } else if BlockPos::from(position) != target { + ctx.look_at(target_center); + ctx.walk(WalkDirection::Forward); + } else { + ctx.walk(WalkDirection::None); + } +} |
