azalea/client_impl/movement.rs
1use azalea_client::{
2 ClientMovementState, SprintDirection, StartSprintEvent, StartWalkEvent, WalkDirection,
3};
4use azalea_entity::{Jumping, LookDirection};
5
6use crate::{Client, client_impl::error::AzaleaResult};
7
8impl Client {
9 /// Set whether we're jumping. This acts as if you held space in
10 /// vanilla.
11 ///
12 /// If you want to jump once, use the `jump` function in `azalea`.
13 ///
14 /// If you're making a realistic client, calling this function every tick is
15 /// recommended.
16 pub fn set_jumping(&self, jumping: bool) -> AzaleaResult<()> {
17 self.query_self::<&mut Jumping, _>(|mut j| **j = jumping)
18 }
19
20 /// Returns whether the player will try to jump next tick.
21 pub fn jumping(&self) -> bool {
22 self.component::<Jumping>().map(|j| **j).unwrap_or_default()
23 }
24
25 pub fn set_crouching(&self, crouching: bool) -> AzaleaResult<()> {
26 self.query_self::<&mut ClientMovementState, _>(|mut p| p.trying_to_crouch = crouching)
27 }
28
29 /// Whether the client is currently trying to sneak.
30 ///
31 /// You may want to check the [`Pose`](azalea_entity::Pose) instead.
32 pub fn crouching(&self) -> bool {
33 self.query_self::<&ClientMovementState, _>(|p| p.trying_to_crouch)
34 .unwrap_or(false)
35 }
36
37 /// Sets the direction the client is looking.
38 ///
39 /// `y_rot` is yaw (looking to the side, between -180 to 180), and `x_rot`
40 /// is pitch (looking up and down, between -90 to 90).
41 ///
42 /// You can get these numbers from the vanilla f3 screen.
43 pub fn set_direction(&self, y_rot: f32, x_rot: f32) -> AzaleaResult<()> {
44 self.query_self::<&mut LookDirection, _>(|mut ld| {
45 ld.update(LookDirection::new(y_rot, x_rot));
46 })
47 }
48
49 /// Returns the direction the client is looking.
50 ///
51 /// See [`Self::set_direction`] for more details.
52 pub fn direction(&self) -> AzaleaResult<LookDirection> {
53 Ok(*self.component::<LookDirection>()?)
54 }
55
56 /// Start walking in the given direction.
57 ///
58 /// To sprint, use [`Client::sprint`]. To stop walking, call walk with
59 /// [`WalkDirection::None`].
60 ///
61 /// # Example
62 ///
63 /// ```rust,no_run
64 /// # use azalea::{Client, WalkDirection};
65 /// # use std::time::Duration;
66 /// # async fn example(mut bot: &Client) {
67 /// // walk for one second
68 /// bot.walk(WalkDirection::Forward);
69 /// tokio::time::sleep(Duration::from_secs(1)).await;
70 /// bot.walk(WalkDirection::None);
71 /// # }
72 /// ```
73 pub fn walk(&self, direction: WalkDirection) {
74 let mut ecs = self.ecs.write();
75 ecs.write_message(StartWalkEvent {
76 entity: self.entity,
77 direction,
78 });
79 }
80
81 /// Returns the [`ClientMovementState`] data for this client.
82 ///
83 /// This includes the direction that we're walking/sprinting in, and whether
84 /// we're trying to sprint or crouch.
85 pub fn movement_state(&self) -> AzaleaResult<ClientMovementState> {
86 Ok(self.component::<ClientMovementState>()?.clone())
87 }
88
89 /// Start sprinting in the given direction.
90 ///
91 /// To stop moving, call [`bot.walk(WalkDirection::None)`](Self::walk).
92 ///
93 /// # Example
94 ///
95 /// ```rust,no_run
96 /// # use azalea::{Client, WalkDirection, SprintDirection};
97 /// # use std::time::Duration;
98 /// # async fn example(bot: &Client) {
99 /// // sprint for one second
100 /// bot.sprint(SprintDirection::Forward);
101 /// tokio::time::sleep(Duration::from_secs(1)).await;
102 /// bot.walk(WalkDirection::None);
103 /// # }
104 /// ```
105 pub fn sprint(&self, direction: SprintDirection) {
106 let mut ecs = self.ecs.write();
107 ecs.write_message(StartSprintEvent {
108 entity: self.entity,
109 direction,
110 });
111 }
112}