Skip to main content

azalea_protocol/packets/game/
s_use_item_on.rs

1use std::io::{self, Cursor, Write};
2
3use azalea_buf::{AzBuf, BufReadError};
4use azalea_core::{
5    direction::Direction,
6    hit_result::BlockHitResult,
7    position::{BlockPos, Vec3, Vec3f32},
8};
9use azalea_protocol_macros::ServerboundGamePacket;
10
11use crate::packets::game::s_interact::InteractionHand;
12
13#[derive(AzBuf, Clone, Debug, PartialEq, ServerboundGamePacket)]
14pub struct ServerboundUseItemOn {
15    pub hand: InteractionHand,
16    pub block_hit: BlockHit,
17    #[var]
18    pub seq: u32,
19}
20
21#[derive(Clone, Debug, PartialEq)]
22pub struct BlockHit {
23    /// The block that we clicked.
24    pub block_pos: BlockPos,
25    /// The face of the block that was clicked.
26    pub direction: Direction,
27    /// The exact coordinates of the world where the block was clicked.
28    ///
29    /// In the network, this is transmitted as the difference between the
30    /// location and block position.
31    pub location: Vec3,
32    /// Whether the player's head is inside a block.
33    pub inside: bool,
34    /// Whether the player's hitting the world border.
35    pub world_border: bool,
36}
37
38impl AzBuf for BlockHit {
39    fn azalea_read(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> {
40        let block_pos = BlockPos::azalea_read(buf)?;
41        let direction = Direction::azalea_read(buf)?;
42        let cursor = Vec3f32::azalea_read(buf)?;
43        let inside = bool::azalea_read(buf)?;
44        let world_border = bool::azalea_read(buf)?;
45        Ok(Self {
46            block_pos,
47            direction,
48            location: Vec3 {
49                x: f64::from(block_pos.x) + f64::from(cursor.x),
50                y: f64::from(block_pos.y) + f64::from(cursor.y),
51                z: f64::from(block_pos.z) + f64::from(cursor.z),
52            },
53            inside,
54            world_border,
55        })
56    }
57    fn azalea_write(&self, buf: &mut impl Write) -> io::Result<()> {
58        self.block_pos.azalea_write(buf)?;
59        self.direction.azalea_write(buf)?;
60        let cursor = Vec3 {
61            x: self.location.x - f64::from(self.block_pos.x),
62            y: self.location.y - f64::from(self.block_pos.y),
63            z: self.location.z - f64::from(self.block_pos.z),
64        };
65        Vec3f32::from(cursor).azalea_write(buf)?;
66        self.inside.azalea_write(buf)?;
67        self.world_border.azalea_write(buf)?;
68        Ok(())
69    }
70}
71
72impl From<&BlockHitResult> for BlockHit {
73    /// Converts a [`BlockHitResult`] to a [`BlockHit`].
74    ///
75    /// The only difference is that the `miss` field is not present in
76    /// [`BlockHit`].
77    fn from(hit_result: &BlockHitResult) -> Self {
78        Self {
79            block_pos: hit_result.block_pos,
80            direction: hit_result.direction,
81            location: hit_result.location,
82            inside: hit_result.inside,
83            world_border: hit_result.world_border,
84        }
85    }
86}