azalea/pathfinder/
rel_block_pos.rs

1use std::ops::{Add, Mul};
2
3use azalea_core::position::BlockPos;
4
5/// An offset from a block position.
6///
7/// This fits in 64 bits, so it's more efficient than a BlockPos in some cases.
8///
9/// The X and Z are limited to ±32k.
10#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
11#[repr(C)]
12pub struct RelBlockPos {
13    pub x: i16,
14    pub z: i16,
15    /// Note that the y isn't relative.
16    pub y: i32,
17}
18
19impl RelBlockPos {
20    pub fn get_origin(origin: BlockPos) -> Self {
21        Self::new(0, origin.y, 0)
22    }
23
24    #[inline]
25    pub fn new(x: i16, y: i32, z: i16) -> Self {
26        Self { x, y, z }
27    }
28
29    #[inline]
30    pub fn apply(self, origin: BlockPos) -> BlockPos {
31        BlockPos::new(origin.x + self.x as i32, self.y, origin.z + self.z as i32)
32    }
33
34    /// Create a new [`RelBlockPos`] from a given origin and new position.
35    #[inline]
36    pub fn from_origin(origin: BlockPos, new: BlockPos) -> Self {
37        Self {
38            x: (new.x - origin.x) as i16,
39            y: new.y,
40            z: (new.z - origin.z) as i16,
41        }
42    }
43
44    #[inline]
45    pub fn up(&self, y: i32) -> Self {
46        Self {
47            x: self.x,
48            y: self.y + y,
49            z: self.z,
50        }
51    }
52    #[inline]
53    pub fn down(&self, y: i32) -> Self {
54        Self {
55            x: self.x,
56            y: self.y - y,
57            z: self.z,
58        }
59    }
60    #[inline]
61    pub fn north(&self, z: i16) -> Self {
62        Self {
63            x: self.x,
64            y: self.y,
65            z: self.z - z,
66        }
67    }
68    #[inline]
69    pub fn south(&self, z: i16) -> Self {
70        Self {
71            x: self.x,
72            y: self.y,
73            z: self.z + z,
74        }
75    }
76    #[inline]
77    pub fn east(&self, x: i16) -> Self {
78        Self {
79            x: self.x + x,
80            y: self.y,
81            z: self.z,
82        }
83    }
84    #[inline]
85    pub fn west(&self, x: i16) -> Self {
86        Self {
87            x: self.x - x,
88            y: self.y,
89            z: self.z,
90        }
91    }
92}
93
94impl Add<RelBlockPos> for RelBlockPos {
95    type Output = RelBlockPos;
96
97    fn add(self, rhs: RelBlockPos) -> Self::Output {
98        Self {
99            x: self.x + rhs.x,
100            y: self.y + rhs.y,
101            z: self.z + rhs.z,
102        }
103    }
104}
105impl Mul<i16> for RelBlockPos {
106    type Output = RelBlockPos;
107
108    fn mul(self, rhs: i16) -> Self::Output {
109        Self {
110            x: self.x * rhs,
111            y: self.y * rhs as i32,
112            z: self.z * rhs,
113        }
114    }
115}