aboutsummaryrefslogtreecommitdiff
path: root/azalea/src/entity_ref/shared_impls.rs
diff options
context:
space:
mode:
authormat <27899617+mat-1@users.noreply.github.com>2025-12-28 21:54:12 -0600
committerGitHub <noreply@github.com>2025-12-28 21:54:12 -0600
commit39488a6585ce969af93f43ece1ffb1174dc95e1d (patch)
tree49b63b2321b974a7c6425e53b8602a0b4500f092 /azalea/src/entity_ref/shared_impls.rs
parent25e441944412038da2be4e64854e59169d58305b (diff)
downloadazalea-drasl-39488a6585ce969af93f43ece1ffb1174dc95e1d.tar.xz
Implement `EntityRef` (#299)
* start implementing EntityRef struct * use EntityRef and impl more functions for it * fix doctests * typo * slightly reword some docs * update changelog
Diffstat (limited to 'azalea/src/entity_ref/shared_impls.rs')
-rw-r--r--azalea/src/entity_ref/shared_impls.rs178
1 files changed, 178 insertions, 0 deletions
diff --git a/azalea/src/entity_ref/shared_impls.rs b/azalea/src/entity_ref/shared_impls.rs
new file mode 100644
index 00000000..3c24b836
--- /dev/null
+++ b/azalea/src/entity_ref/shared_impls.rs
@@ -0,0 +1,178 @@
+use azalea_core::position::Vec3;
+use azalea_entity::{
+ Attributes, Dead, EntityUuid, Position, dimensions::EntityDimensions, metadata::Health,
+};
+use azalea_world::{InstanceName, MinecraftEntityId};
+use uuid::Uuid;
+
+use super::EntityRef;
+use crate::Client;
+
+macro_rules! impl_entity_functions {
+ ( $(
+ Client:
+ $(#[$client_doc:meta])*
+ EntityRef:
+ $(#[$entityref_doc:meta])*
+ pub fn $fn_name:ident (&$fn_self:ident) -> $fn_returns:ty $fn_impl:block
+ )* ) => {
+ $(
+ impl Client {
+ $(#[$client_doc])*
+ pub fn $fn_name(&$fn_self) -> $fn_returns $fn_impl
+ }
+ impl EntityRef {
+ $(#[$entityref_doc])*
+ pub fn $fn_name(&$fn_self) -> $fn_returns $fn_impl
+ }
+ )*
+ };
+}
+
+// these functions are defined this way because we want them to be duplicated
+// for both Client and EntityRef but still have their own documentation
+impl_entity_functions! {
+ Client:
+ /// Get the client's position in the world, which is the same as its feet
+ /// position.
+ ///
+ /// This is a shortcut for `**bot.component::<Position>()`.
+ ///
+ /// To get the client's eye position, use [`Self::eye_position`].
+ ///
+ /// Note that this value is given a default of [`Vec3::ZERO`] when it
+ /// receives the login packet, its true position may be set ticks
+ /// later.
+ EntityRef:
+ /// Get the entity's position in the world, which is the same as its feet
+ /// position.
+ ///
+ /// To get the client's eye position, use [`Self::eye_position`].
+ ///
+ /// Also see [`Client::position`].
+ pub fn position(&self) -> Vec3 {
+ **self.component::<Position>()
+ }
+
+ Client:
+ /// Get the bounding box dimensions for our client, which contains our
+ /// width, height, and eye height.
+ ///
+ /// This is a shortcut for
+ /// `self.component::<EntityDimensions>()`.
+ EntityRef:
+ /// Get the bounding box dimensions for the entity, which contains its
+ /// width, height, and eye height.
+ ///
+ /// Also see [`Client::dimensions`]
+ pub fn dimensions(&self) -> EntityDimensions {
+ self.component::<EntityDimensions>().clone()
+ }
+
+ Client:
+ /// Get the position of this client's eyes.
+ ///
+ /// Also see [`Self::position`].
+ ///
+ /// This is a shortcut for
+ /// `bot.position().up(bot.dimensions().eye_height)`.
+ EntityRef:
+ /// Get the position of this entity's eyes.
+ ///
+ /// Also see [`Client::eye_position`].
+ pub fn eye_position(&self) -> Vec3 {
+ self.query_self::<(&Position, &EntityDimensions), _>(|(pos, dim)| {
+ pos.up(dim.eye_height as f64)
+ })
+ }
+
+ Client:
+ /// Get the health of this client.
+ ///
+ /// This is a shortcut for `*bot.component::<Health>()`.
+ EntityRef:
+ /// Get the health of this entity.
+ ///
+ /// Also see [`Client::health`].
+ pub fn health(&self) -> f32 {
+ **self.component::<Health>()
+ }
+
+ Client:
+ /// Get the Minecraft UUID of this client.
+ ///
+ /// This is a shortcut for `**self.component::<EntityUuid>()`.
+ EntityRef:
+ /// Get the Minecraft UUID of this entity.
+ ///
+ /// Also see [`Client::uuid`].
+ pub fn uuid(&self) -> Uuid {
+ **self.component::<EntityUuid>()
+ }
+
+ Client:
+ /// Get the Minecraft ID of this client.
+ ///
+ /// See [`MinecraftEntityId`] for more details. For persistent identifiers,
+ /// consider using [`Self::uuid`] instead.
+ ///
+ /// This is a shortcut for `**self.component::<MinecraftEntityId>()`.
+ EntityRef:
+ /// Get the Minecraft UUID of this entity.
+ ///
+ /// See [`MinecraftEntityId`] for more details. For persistent identifiers,
+ /// consider using [`Self::uuid`] instead.
+ ///
+ /// Also see [`Client::minecraft_id`].
+ pub fn minecraft_id(&self) -> MinecraftEntityId {
+ *self.component::<MinecraftEntityId>()
+ }
+
+ Client:
+ /// Returns the attribute values of our player, which can be used to
+ /// determine things like our movement speed.
+ EntityRef:
+ /// Returns the attribute values of the entity, which can be used to
+ /// determine things like its movement speed.
+ 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()
+ }
+
+ Client:
+ /// 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"))]
+ EntityRef:
+ /// Get the name of the instance (world) that the entity is in.
+ ///
+ /// This can be used to check if the entity is in the same world as another
+ /// entity.
+ ///
+ /// Also see [`Client::instance_name`],
+ #[doc(alias("world_name", "dimension_name"))]
+ pub fn instance_name(&self) -> InstanceName {
+ (*self.component::<InstanceName>()).clone()
+ }
+
+ Client:
+ /// Returns whether the client is alive and in the world.
+ ///
+ /// You should avoid using this if you have auto-respawn enabled (which is
+ /// the default), instead consider watching for
+ /// [`Event::Death`](crate::Event::Death) instead.
+ EntityRef:
+ /// Returns whether the entity is alive and hasn't despawned.
+ ///
+ /// Unlike most functions in `EntityRef`, this one will not panic if the
+ /// entity is despawned. Because of this, it may be useful to check `is_alive`
+ /// before calling functions that request data from the world.
+ ///
+ /// Also see [`Client::is_alive`].
+ pub fn is_alive(&self) -> bool {
+ self.query_self::<Option<&Dead>, _>(|dead| dead.is_none())
+ }
+}