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)]
11pub struct RelBlockPos {
12    pub x: i16,
13    /// Note that the y isn't relative.
14    pub y: i32,
15    pub z: i16,
16}
17
18impl RelBlockPos {
19    pub fn get_origin(origin: BlockPos) -> Self {
20        Self::new(0, origin.y, 0)
21    }
22
23    #[inline]
24    pub fn new(x: i16, y: i32, z: i16) -> Self {
25        Self { x, y, z }
26    }
27
28    #[inline]
29    pub fn apply(self, origin: BlockPos) -> BlockPos {
30        BlockPos::new(origin.x + self.x as i32, self.y, origin.z + self.z as i32)
31    }
32
33    /// Create a new [`RelBlockPos`] from a given origin and new position.
34    #[inline]
35    pub fn from_origin(origin: BlockPos, new: BlockPos) -> Self {
36        Self {
37            x: (new.x - origin.x) as i16,
38            y: new.y,
39            z: (new.z - origin.z) as i16,
40        }
41    }
42
43    #[inline]
44    pub fn up(&self, y: i32) -> Self {
45        Self {
46            x: self.x,
47            y: self.y + y,
48            z: self.z,
49        }
50    }
51    #[inline]
52    pub fn down(&self, y: i32) -> Self {
53        Self {
54            x: self.x,
55            y: self.y - y,
56            z: self.z,
57        }
58    }
59    #[inline]
60    pub fn north(&self, z: i16) -> Self {
61        Self {
62            x: self.x,
63            y: self.y,
64            z: self.z - z,
65        }
66    }
67    #[inline]
68    pub fn south(&self, z: i16) -> Self {
69        Self {
70            x: self.x,
71            y: self.y,
72            z: self.z + z,
73        }
74    }
75    #[inline]
76    pub fn east(&self, x: i16) -> Self {
77        Self {
78            x: self.x + x,
79            y: self.y,
80            z: self.z,
81        }
82    }
83    #[inline]
84    pub fn west(&self, x: i16) -> Self {
85        Self {
86            x: self.x - x,
87            y: self.y,
88            z: self.z,
89        }
90    }
91}
92
93impl Add<RelBlockPos> for RelBlockPos {
94    type Output = RelBlockPos;
95
96    fn add(self, rhs: RelBlockPos) -> Self::Output {
97        Self {
98            x: self.x + rhs.x,
99            y: self.y + rhs.y,
100            z: self.z + rhs.z,
101        }
102    }
103}
104impl Mul<i16> for RelBlockPos {
105    type Output = RelBlockPos;
106
107    fn mul(self, rhs: i16) -> Self::Output {
108        Self {
109            x: self.x * rhs,
110            y: self.y * rhs as i32,
111            z: self.z * rhs,
112        }
113    }
114}