aboutsummaryrefslogtreecommitdiff
path: root/azalea/src/client_impl
diff options
context:
space:
mode:
Diffstat (limited to 'azalea/src/client_impl')
-rw-r--r--azalea/src/client_impl/entity_query.rs31
-rw-r--r--azalea/src/client_impl/interact.rs10
-rw-r--r--azalea/src/client_impl/inventory.rs7
-rw-r--r--azalea/src/client_impl/mod.rs24
-rw-r--r--azalea/src/client_impl/movement.rs5
5 files changed, 52 insertions, 25 deletions
diff --git a/azalea/src/client_impl/entity_query.rs b/azalea/src/client_impl/entity_query.rs
index ae623dc7..683d755e 100644
--- a/azalea/src/client_impl/entity_query.rs
+++ b/azalea/src/client_impl/entity_query.rs
@@ -21,8 +21,9 @@ impl Client {
///
/// This returns a reference to the component wrapped by a read guard. This
/// makes the component cheap to access, but means that the ECS cannot be
- /// mutated while it's in scope. In some cases, it may be simpler for you to
- /// immediately clone the component after accessing it.
+ /// mutated while it's in scope (it will cause a deadlock). In some cases,
+ /// it may be simpler for you to immediately clone the component after
+ /// accessing it.
///
/// If the component isn't guaranteed to be present, consider using
/// [`Self::get_component`] instead.
@@ -227,15 +228,19 @@ impl Client {
pub fn nearest_entities_by<Q: QueryData, F: QueryFilter>(
&self,
predicate: impl EntityPredicate<Q, F>,
- ) -> Vec<Entity> {
- let Some(instance_name) = self.get_component::<InstanceName>() else {
- return vec![];
- };
- let Some(position) = self.get_component::<Position>() else {
- return vec![];
+ ) -> Box<[Entity]> {
+ let (instance_name, position) = {
+ let Some(instance_name) = self.get_component::<InstanceName>() else {
+ return Box::new([]);
+ };
+ let Some(position) = self.get_component::<Position>() else {
+ return Box::new([]);
+ };
+
+ (instance_name.clone(), **position)
};
- let (instance_name, position) = (instance_name.clone(), *position);
- predicate.find_all_sorted(self.ecs.clone(), &instance_name, (&position).into())
+
+ predicate.find_all_sorted(self.ecs.clone(), &instance_name, position)
}
/// Get a component from an entity.
@@ -291,7 +296,7 @@ pub trait EntityPredicate<Q: QueryData, Filter: QueryFilter> {
ecs_lock: Arc<RwLock<World>>,
instance_name: &InstanceName,
nearest_to: Vec3,
- ) -> Vec<Entity>;
+ ) -> Box<[Entity]>;
}
impl<F, Q: QueryData, Filter: QueryFilter> EntityPredicate<Q, Filter> for F
where
@@ -316,7 +321,7 @@ where
ecs_lock: Arc<RwLock<World>>,
instance_name: &InstanceName,
nearest_to: Vec3,
- ) -> Vec<Entity> {
+ ) -> Box<[Entity]> {
let mut ecs = ecs_lock.write();
let mut query = ecs.query_filtered::<(Entity, &InstanceName, &Position, Q), Filter>();
let mut entities = query
@@ -333,6 +338,6 @@ where
entities
.into_iter()
.map(|(e, _)| e)
- .collect::<Vec<Entity>>()
+ .collect::<Box<[Entity]>>()
}
}
diff --git a/azalea/src/client_impl/interact.rs b/azalea/src/client_impl/interact.rs
index 8a9cf475..b3cda1e2 100644
--- a/azalea/src/client_impl/interact.rs
+++ b/azalea/src/client_impl/interact.rs
@@ -1,11 +1,17 @@
-use azalea_client::interact::{EntityInteractEvent, StartUseItemEvent};
-use azalea_core::position::BlockPos;
+use azalea_client::interact::{EntityInteractEvent, StartUseItemEvent, pick::HitResultComponent};
+use azalea_core::{hit_result::HitResult, position::BlockPos};
use azalea_protocol::packets::game::s_interact::InteractionHand;
use bevy_ecs::entity::Entity;
use crate::Client;
impl Client {
+ /// Returns the current [`HitResult`], which is the block or entity in the
+ /// client's crosshair.
+ pub fn hit_result(&self) -> HitResult {
+ (**self.component::<HitResultComponent>()).clone()
+ }
+
/// Right-click a block.
///
/// The behavior of this depends on the target block,
diff --git a/azalea/src/client_impl/inventory.rs b/azalea/src/client_impl/inventory.rs
index fc1e2e73..72a05136 100644
--- a/azalea/src/client_impl/inventory.rs
+++ b/azalea/src/client_impl/inventory.rs
@@ -7,8 +7,11 @@ use crate::Client;
impl Client {
/// Return the menu that is currently open, or the player's inventory if no
/// menu is open.
+ ///
+ /// If you need to interact with the menu, consider using
+ /// [`Self::open_inventory`] instead.
pub fn menu(&self) -> Menu {
- self.query_self::<&Inventory, _>(|inv| inv.menu().clone())
+ self.component::<Inventory>().menu().clone()
}
/// Returns the index of the hotbar slot that's currently selected.
@@ -19,7 +22,7 @@ impl Client {
///
/// You can use [`Self::set_selected_hotbar_slot`] to change it.
pub fn selected_hotbar_slot(&self) -> u8 {
- self.query_self::<&Inventory, _>(|inv| inv.selected_hotbar_slot)
+ self.component::<Inventory>().selected_hotbar_slot
}
/// Update the selected hotbar slot index.
diff --git a/azalea/src/client_impl/mod.rs b/azalea/src/client_impl/mod.rs
index bbbe23e0..419fc27e 100644
--- a/azalea/src/client_impl/mod.rs
+++ b/azalea/src/client_impl/mod.rs
@@ -35,7 +35,7 @@ use bevy_ecs::{
resource::Resource,
world::{Mut, World},
};
-use parking_lot::{MappedRwLockReadGuard, RwLock};
+use parking_lot::RwLock;
use tokio::sync::mpsc;
use uuid::Uuid;
@@ -308,9 +308,7 @@ impl Client {
// the login packet tells us the world name
self.query_self::<Option<&InstanceName>, _>(|ins| ins.is_some())
}
-}
-impl Client {
/// Get the position of this client.
///
/// This is a shortcut for `Vec3::from(&bot.component::<Position>())`.
@@ -395,10 +393,26 @@ impl Client {
(**self.component::<GameProfileComponent>()).clone()
}
+ /// Returns the [`Account`] for our client.
+ pub fn account(&self) -> Account {
+ self.component::<Account>().clone()
+ }
+
/// Returns the attribute values of our player, which can be used to
/// determine things like our movement speed.
- pub fn attributes(&self) -> MappedRwLockReadGuard<'_, Attributes> {
- self.component::<Attributes>()
+ pub fn attributes(&self) -> Attributes {
+ // this *could* return a mapped read guard for performance but that rarely
+ // matters and it's just easier for the user if it doesn't.
+ self.component::<Attributes>().clone()
+ }
+
+ /// Get the name of the instance (world) that the bot is in.
+ ///
+ /// This can be used to check if the client is in the same world as another
+ /// entity.
+ #[doc(alias("world_name", "dimension_name"))]
+ pub fn instance_name(&self) -> InstanceName {
+ (*self.component::<InstanceName>()).clone()
}
/// A convenience function to get the Minecraft Uuid of a player by their
diff --git a/azalea/src/client_impl/movement.rs b/azalea/src/client_impl/movement.rs
index a708e5f6..6532997d 100644
--- a/azalea/src/client_impl/movement.rs
+++ b/azalea/src/client_impl/movement.rs
@@ -48,9 +48,8 @@ impl Client {
/// Returns the direction the client is looking.
///
/// See [`Self::set_direction`] for more details.
- pub fn direction(&self) -> (f32, f32) {
- let look_direction = *self.component::<LookDirection>();
- (look_direction.y_rot(), look_direction.x_rot())
+ pub fn direction(&self) -> LookDirection {
+ *self.component::<LookDirection>()
}
/// Start walking in the given direction.