aboutsummaryrefslogtreecommitdiff
path: root/azalea/src/pathfinder/moves/mod.rs
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2023-12-15 11:26:40 -0600
committerGitHub <noreply@github.com>2023-12-15 11:26:40 -0600
commita707e2eb82b74994a16083b31fa4576332cf1995 (patch)
treedb6c2ac94dd73590befd68a9b1b0ef960410b0df /azalea/src/pathfinder/moves/mod.rs
parent59e140ddd655c7dc6e35109b91286118c51bcc06 (diff)
downloadazalea-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/mod.rs')
-rw-r--r--azalea/src/pathfinder/moves/mod.rs108
1 files changed, 100 insertions, 8 deletions
diff --git a/azalea/src/pathfinder/moves/mod.rs b/azalea/src/pathfinder/moves/mod.rs
index e5b837ea..bb10b192 100644
--- a/azalea/src/pathfinder/moves/mod.rs
+++ b/azalea/src/pathfinder/moves/mod.rs
@@ -1,14 +1,24 @@
pub mod basic;
pub mod parkour;
-use std::fmt::Debug;
-
-use crate::{JumpEvent, LookAtEvent};
-
-use super::{astar, mining::MiningCache, world::CachedWorld};
-use azalea_client::{SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection};
+use std::{fmt::Debug, sync::Arc};
+
+use crate::{auto_tool::best_tool_in_hotbar_for_block, JumpEvent, LookAtEvent};
+
+use super::{
+ astar,
+ mining::MiningCache,
+ world::{is_block_state_passable, CachedWorld},
+};
+use azalea_client::{
+ inventory::SetSelectedHotbarSlotEvent, mining::StartMiningBlockEvent, SprintDirection,
+ StartSprintEvent, StartWalkEvent, WalkDirection,
+};
use azalea_core::position::{BlockPos, Vec3};
+use azalea_inventory::Menu;
+use azalea_world::Instance;
use bevy_ecs::{entity::Entity, event::EventWriter};
+use parking_lot::RwLock;
type Edge = astar::Edge<BlockPos, MoveData>;
@@ -35,7 +45,7 @@ impl Debug for MoveData {
}
}
-pub struct ExecuteCtx<'w1, 'w2, 'w3, 'w4, 'a> {
+pub struct ExecuteCtx<'w1, 'w2, 'w3, 'w4, 'w5, 'w6, 'a> {
pub entity: Entity,
/// The node that we're trying to reach.
pub target: BlockPos,
@@ -43,14 +53,19 @@ pub struct ExecuteCtx<'w1, 'w2, 'w3, 'w4, 'a> {
pub start: BlockPos,
pub position: Vec3,
pub physics: &'a azalea_entity::Physics,
+ pub is_currently_mining: bool,
+ pub instance: Arc<RwLock<Instance>>,
+ pub menu: Menu,
pub look_at_events: &'a mut EventWriter<'w1, LookAtEvent>,
pub sprint_events: &'a mut EventWriter<'w2, StartSprintEvent>,
pub walk_events: &'a mut EventWriter<'w3, StartWalkEvent>,
pub jump_events: &'a mut EventWriter<'w4, JumpEvent>,
+ pub start_mining_events: &'a mut EventWriter<'w5, StartMiningBlockEvent>,
+ pub set_selected_hotbar_slot_events: &'a mut EventWriter<'w6, SetSelectedHotbarSlotEvent>,
}
-impl ExecuteCtx<'_, '_, '_, '_, '_> {
+impl ExecuteCtx<'_, '_, '_, '_, '_, '_, '_> {
pub fn look_at(&mut self, position: Vec3) {
self.look_at_events.send(LookAtEvent {
entity: self.entity,
@@ -63,6 +78,13 @@ impl ExecuteCtx<'_, '_, '_, '_, '_> {
});
}
+ pub fn look_at_exact(&mut self, position: Vec3) {
+ self.look_at_events.send(LookAtEvent {
+ entity: self.entity,
+ position,
+ });
+ }
+
pub fn sprint(&mut self, direction: SprintDirection) {
self.sprint_events.send(StartSprintEvent {
entity: self.entity,
@@ -82,6 +104,76 @@ impl ExecuteCtx<'_, '_, '_, '_, '_> {
entity: self.entity,
});
}
+
+ /// Returns whether this block could be mined.
+ pub fn should_mine(&mut self, block: BlockPos) -> bool {
+ let block_state = self
+ .instance
+ .read()
+ .get_block_state(&block)
+ .unwrap_or_default();
+ if is_block_state_passable(block_state) {
+ // block is already passable, no need to mine it
+ return false;
+ }
+
+ true
+ }
+
+ /// Mine the block at the given position. Returns whether the block is being
+ /// mined.
+ pub fn mine(&mut self, block: BlockPos) -> bool {
+ let block_state = self
+ .instance
+ .read()
+ .get_block_state(&block)
+ .unwrap_or_default();
+ if is_block_state_passable(block_state) {
+ // block is already passable, no need to mine it
+ return false;
+ }
+
+ let best_tool_result = best_tool_in_hotbar_for_block(block_state, &self.menu);
+
+ self.set_selected_hotbar_slot_events
+ .send(SetSelectedHotbarSlotEvent {
+ entity: self.entity,
+ slot: best_tool_result.index as u8,
+ });
+
+ self.is_currently_mining = true;
+
+ self.walk(WalkDirection::None);
+ self.look_at_exact(block.center());
+ self.start_mining_events.send(StartMiningBlockEvent {
+ entity: self.entity,
+ position: block,
+ });
+
+ true
+ }
+
+ /// Mine the given block, but make sure the player is standing at the start
+ /// of the current node first.
+ pub fn mine_while_at_start(&mut self, block: BlockPos) -> bool {
+ let horizontal_distance_from_start = (self.start.center() - self.position)
+ .horizontal_distance_sqr()
+ .sqrt();
+ let at_start_position =
+ BlockPos::from(self.position) == self.start && horizontal_distance_from_start < 0.25;
+
+ if self.should_mine(block) {
+ if at_start_position {
+ self.mine(block);
+ } else {
+ self.look_at(self.start.center());
+ self.walk(WalkDirection::Forward);
+ }
+ true
+ } else {
+ false
+ }
+ }
}
pub struct IsReachedCtx<'a> {