azalea/entity_ref/shared_impls.rs
1use azalea_core::{entity_id::MinecraftEntityId, position::Vec3};
2use azalea_entity::{
3 Attributes, Dead, Physics, Position, dimensions::EntityDimensions, metadata::Health,
4};
5use azalea_world::WorldName;
6
7use super::EntityRef;
8use crate::{Client, client_impl::error::AzaleaResult};
9
10macro_rules! impl_entity_functions {
11 ( $(
12 Client:
13 $(#[$client_doc:meta])*
14 EntityRef:
15 $(#[$entityref_doc:meta])*
16 pub fn $fn_name:ident (&$fn_self:ident) -> $fn_returns:ty $fn_impl:block
17 )* ) => {
18 $(
19 impl Client {
20 $(#[$client_doc])*
21 pub fn $fn_name(&$fn_self) -> $fn_returns $fn_impl
22 }
23 impl EntityRef {
24 $(#[$entityref_doc])*
25 pub fn $fn_name(&$fn_self) -> $fn_returns $fn_impl
26 }
27 )*
28 };
29}
30
31// these functions are defined this way because we want them to be duplicated
32// for both Client and EntityRef but still have their own documentation
33impl_entity_functions! {
34 Client:
35 /// Get the client's position in the world, which is the same as its feet
36 /// position.
37 ///
38 /// This is a shortcut for `**bot.component::<Position>()`.
39 ///
40 /// To get the client's eye position, use [`Self::eye_position`].
41 ///
42 /// Note that this value is given a default of [`Vec3::ZERO`] when it
43 /// receives the login packet, its true position may be set ticks
44 /// later.
45 EntityRef:
46 /// Get the entity's position in the world, which is the same as its feet
47 /// position.
48 ///
49 /// To get the client's eye position, use [`Self::eye_position`].
50 ///
51 /// Also see [`Client::position`].
52 pub fn position(&self) -> AzaleaResult<Vec3> {
53 Ok(**self.component::<Position>()?)
54 }
55
56 Client:
57 /// Get the bounding box dimensions for our client, which contains our
58 /// width, height, and eye height.
59 ///
60 /// This is a shortcut for
61 /// `self.component::<EntityDimensions>()`.
62 EntityRef:
63 /// Get the bounding box dimensions for the entity, which contains its
64 /// width, height, and eye height.
65 ///
66 /// Also see [`Client::dimensions`]
67 pub fn dimensions(&self) -> AzaleaResult<EntityDimensions> {
68 Ok(self.component::<EntityDimensions>()?.clone())
69 }
70
71 Client:
72 /// Get the position of this client's eyes.
73 ///
74 /// Also see [`Self::position`].
75 ///
76 /// This is a shortcut for
77 /// `bot.position().up(bot.dimensions().eye_height)`.
78 EntityRef:
79 /// Get the position of this entity's eyes.
80 ///
81 /// Also see [`Client::eye_position`].
82 pub fn eye_position(&self) -> AzaleaResult<Vec3> {
83 self.query_self::<(&Position, &EntityDimensions), _>(|(pos, dim)| {
84 pos.up(dim.eye_height as f64)
85 })
86 }
87
88 Client:
89 /// Get the health of this client, typically in the range `0..=20`.
90 ///
91 /// This is a shortcut for `*bot.component::<Health>()`.
92 EntityRef:
93 /// Get the health of this entity, typically in the range `0..=20`.
94 ///
95 /// Also see [`Client::health`].
96 pub fn health(&self) -> AzaleaResult<f32> {
97 Ok(**self.component::<Health>()?)
98 }
99
100 Client:
101 /// Get the Minecraft ID of this client.
102 ///
103 /// See [`MinecraftEntityId`] for more details. For persistent identifiers,
104 /// consider using [`Self::uuid`] instead.
105 ///
106 /// This is a shortcut for `**self.component::<MinecraftEntityId>()`.
107 EntityRef:
108 /// Get the Minecraft ID of this entity.
109 ///
110 /// See [`MinecraftEntityId`] for more details. For persistent identifiers,
111 /// consider using [`Self::uuid`] instead.
112 ///
113 /// Also see [`Client::minecraft_id`].
114 pub fn minecraft_id(&self) -> AzaleaResult<MinecraftEntityId> {
115 Ok(*self.component::<MinecraftEntityId>()?)
116 }
117
118 Client:
119 /// Returns the attribute values of our player, which can be used to
120 /// determine things like our movement speed.
121 EntityRef:
122 /// Returns the attribute values of the entity, which can be used to
123 /// determine things like its movement speed.
124 pub fn attributes(&self) -> AzaleaResult<Attributes> {
125 // this *could* return a mapped read guard for performance but that rarely
126 // matters and it's just easier for the user if it doesn't.
127 Ok(self.component::<Attributes>()?.clone())
128 }
129
130 Client:
131 #[doc(hidden)]
132 #[deprecated = "renamed to `world_name`."]
133 EntityRef:
134 #[doc(hidden)]
135 #[deprecated = "renamed to `world_name`."]
136 pub fn instance_name(&self) -> AzaleaResult<WorldName> {
137 self.world_name()
138 }
139
140 Client:
141 /// Get the name of the world that the bot is in.
142 ///
143 /// This can be used to check if the client is in the same world as another
144 /// entity.
145 #[doc(alias("dimension_name"))]
146 EntityRef:
147 /// Get the name of the world that the entity is in.
148 ///
149 /// This can be used to check if the entity is in the same world as another
150 /// entity.
151 ///
152 /// Also see [`Client::world_name`],
153 #[doc(alias("dimension_name"))]
154 pub fn world_name(&self) -> AzaleaResult<WorldName> {
155 Ok((*self.component::<WorldName>()?).clone())
156 }
157
158 Client:
159 /// Returns whether the client is alive and in the world.
160 ///
161 /// You should avoid using this if you have auto-respawn enabled (which is
162 /// the default), instead consider watching for
163 /// [`Event::Death`](crate::Event::Death) instead.
164 ///
165 /// Also see [`Self::exists`].
166 EntityRef:
167 /// Returns whether the entity is alive and hasn't despawned.
168 ///
169 /// Unlike most functions in `EntityRef`, this one will not panic if the
170 /// entity is despawned. Because of this, it may be useful to check `is_alive`
171 /// before calling functions that request data from the world.
172 ///
173 /// Also see [`Client::is_alive`] and [`Self::exists`].
174 pub fn is_alive(&self) -> bool {
175 self.query_self::<Option<&Dead>, _>(|dead| dead.is_none()).unwrap_or(false)
176 }
177
178 Client:
179 /// Returns whether the client is in the world (has been assigned an entity ID).
180 ///
181 /// Like [`Self::is_alive`], this will not panic.
182 EntityRef:
183 /// Returns whether the entity is in the world and hasn't despawned.
184 ///
185 /// Like [`Self::is_alive`], this will not panic.
186 ///
187 /// Also see [`Client::exists`].
188 pub fn exists(&self) -> bool {
189 self.query_self::<Option<&MinecraftEntityId>, _>(|entity_id| entity_id.is_some()).unwrap_or(false)
190 }
191
192 Client:
193 /// Returns the complete [`Physics`] data for this client, including velocity, bounding box,
194 /// collisions, etc.
195 EntityRef:
196 /// Returns the complete [`Physics`] data for this entity, including velocity, bounding box,
197 /// collisions, etc.
198 ///
199 /// Also see [`Client::physics`].
200 pub fn physics(&self) -> AzaleaResult<Physics> {
201 Ok(self.component::<Physics>()?.clone())
202 }
203}