diff options
| author | mat <27899617+mat-1@users.noreply.github.com> | 2025-12-28 21:54:12 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-12-28 21:54:12 -0600 |
| commit | 39488a6585ce969af93f43ece1ffb1174dc95e1d (patch) | |
| tree | 49b63b2321b974a7c6425e53b8602a0b4500f092 /azalea/src/entity_ref/shared_impls.rs | |
| parent | 25e441944412038da2be4e64854e59169d58305b (diff) | |
| download | azalea-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.rs | 178 |
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()) + } +} |
