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