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/mod.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/mod.rs')
| -rw-r--r-- | azalea/src/pathfinder/moves/mod.rs | 108 |
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> { |
