1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
|
pub mod shared_impls;
use std::fmt::Debug;
use azalea_entity::{EntityKindComponent, EntityUuid};
use azalea_registry::builtin::EntityKind;
use bevy_ecs::{
component::Component,
entity::Entity,
query::{QueryData, QueryEntityError, QueryItem},
};
use parking_lot::MappedRwLockReadGuard;
use uuid::Uuid;
use crate::{
Client,
client_impl::error::{AzaleaResult, MissingComponentError},
};
/// A reference to an entity in a world.
///
/// This is different from [`Entity`], since you can perform actions with just
/// an `EntityRef` instead of it only being an identifier.
///
/// Most functions on `EntityRef` that return a value will result in a panic if
/// the client has despawned, so if your code involves waiting, you should check
/// [`Self::is_alive`] or [`Self::exists`] before calling those functions.
///
/// Also, since `EntityRef` stores the [`Client`] alongside the entity, this
/// means that it supports interactions such as [`Self::attack`].
///
/// Not to be confused with Bevy's [`EntityRef`](bevy_ecs::world::EntityRef).
#[derive(Clone)]
pub struct EntityRef {
client: Client,
entity: Entity,
}
impl EntityRef {
pub fn new(client: Client, entity: Entity) -> Self {
Self { client, entity }
}
/// Returns the ECS identifier for the entity.
pub fn id(&self) -> Entity {
self.entity
}
/// Get a component on the entity.
///
/// This allows you to access certain data stored about the entity that
/// isn't accessible in a simpler way.
///
/// See [`Client::component`] for more details.
///
/// # Panics
///
/// This will panic if the component doesn't exist on the client. Use
/// [`Self::get_component`] to avoid this.
///
/// # Examples
///
/// ```
/// # use azalea_world::WorldName;
/// # fn example(client: &azalea::Client) {
/// let world_name = client.component::<WorldName>();
/// # }
pub fn component<T: Component>(
&self,
) -> Result<MappedRwLockReadGuard<'_, T>, MissingComponentError> {
self.client.entity_component(self.entity)
}
/// Get a component on this client, or `None` if it doesn't exist.
///
/// If the component is guaranteed to be present, consider using
/// [`Self::component`].
///
/// See [`Client::component`] for more details.
pub fn get_component<T: Component>(&self) -> Option<MappedRwLockReadGuard<'_, T>> {
self.client.get_entity_component(self.entity)
}
/// Query the ECS for data from the entity.
///
/// You can use this to mutate data on the entity.
///
/// Also see [`Client::query_self`] and [`Client::query_entity`].
///
/// # Errors
///
/// This will return an error if the entity doesn't exist or is missing a
/// component required by the query.
pub fn query_self<D: QueryData, R>(
&self,
f: impl FnOnce(QueryItem<D>) -> R,
) -> AzaleaResult<R> {
self.client.query_entity(self.entity, f)
}
#[doc(hidden)]
#[deprecated = "replaced with `Self::query_self`."]
pub fn try_query_self<D: QueryData, R>(
&self,
f: impl FnOnce(QueryItem<D>) -> R,
) -> Result<R, QueryEntityError> {
#[allow(deprecated)]
self.client.try_query_entity(self.entity, f)
}
}
impl Debug for EntityRef {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("EntityRef")
.field("client", &self.client.entity)
.field("entity", &self.entity)
.finish()
}
}
impl EntityRef {
/// Returns the type of entity that this is.
pub fn kind(&self) -> AzaleaResult<EntityKind> {
Ok(**self.component::<EntityKindComponent>()?)
}
/// Get the Minecraft UUID of this entity.
///
/// Also see [`Client::uuid`].
pub fn uuid(&self) -> AzaleaResult<Uuid> {
// note: this isn't in shared_impls because the Client counterpart isn't
// fallible
Ok(**self.component::<EntityUuid>()?)
}
}
impl EntityRef {
/// Attack this entity from the client that created this `EntityRef`.
///
/// Also see [`Client::attack`].
pub fn attack(&self) {
self.client.attack(self.entity);
}
/// Right-click this entity from the client that created this `EntityRef`.
///
/// See [`Client::entity_interact`] for more information.
pub fn interact(&self) {
self.client.entity_interact(self.entity);
}
/// Look at this entity from the client that created the `EntityRef`.
pub fn look_at(&self) -> AzaleaResult<()> {
self.client.look_at(self.eye_position()?);
Ok(())
}
/// Returns the distance between the client's feet position and this
/// entity's feet position.
pub fn distance_to_client(&self) -> AzaleaResult<f64> {
Ok(self.position()?.distance_to(self.client.position()?))
}
}
|