aboutsummaryrefslogtreecommitdiff
path: root/azalea-client/src/movement.rs
blob: 5f9533be333cb40aecbf67d140a5f64d5658af15 (plain)
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
use crate::Client;
use azalea_core::EntityPos;
use azalea_protocol::packets::game::serverbound_move_player_pos_rot_packet::ServerboundMovePlayerPacketPosRot;
use azalea_world::MoveEntityError;
use thiserror::Error;

#[derive(Error, Debug)]
pub enum MovePlayerError {
    #[error("Player is not in world")]
    PlayerNotInWorld,
    #[error("{0}")]
    Io(#[from] std::io::Error),
}

impl Client {
    /// Set the client's position to the given coordinates.
    pub async fn move_to(&mut self, new_pos: EntityPos) -> Result<(), MovePlayerError> {
        {
            let mut dimension_lock = self.dimension.lock().unwrap();
            let dimension = dimension_lock.as_mut().unwrap();

            let player_lock = self.player.lock().unwrap();

            let player_id = if let Some(player_lock) = player_lock.entity(dimension) {
                player_lock.id
            } else {
                return Err(MovePlayerError::PlayerNotInWorld);
            };

            match dimension.move_entity(player_id, new_pos) {
                Ok(_) => Ok(()),
                Err(e) => match e {
                    MoveEntityError::EntityDoesNotExist => Err(MovePlayerError::PlayerNotInWorld),
                },
            }?;
        }

        self.conn
            .lock()
            .await
            .write(
                ServerboundMovePlayerPacketPosRot {
                    x: new_pos.x,
                    y: new_pos.y,
                    z: new_pos.z,
                    x_rot: 0.0,
                    y_rot: 0.0,
                    on_ground: false,
                }
                .get(),
            )
            .await?;

        Ok(())
    }
}