mc_core/
pos.rs

1
2
3/// This is a standard structure used to exchange block positions. Coordinates
4/// are signed 32-bits integers.
5#[derive(Debug, Eq, PartialEq, Clone)]
6pub struct BlockPos {
7    pub x: i32,
8    pub y: i32,
9    pub z: i32
10}
11
12impl BlockPos {
13
14    #[inline]
15    pub const fn new(x: i32, y: i32, z: i32) -> Self {
16        Self { x, y, z }
17    }
18
19    #[inline]
20    pub const fn nil() -> Self {
21        Self::new(0, 0, 0)
22    }
23
24    #[inline]
25    pub fn into_array(&self) -> [i32; 3] {
26        [self.x, self.y, self.z]
27    }
28
29    #[inline]
30    pub fn add(&self, dx: i32, dy: i32, dz: i32) -> Self {
31        Self {
32            x: self.x + dx,
33            y: self.y + dy,
34            z: self.z + dz,
35        }
36    }
37
38    #[inline]
39    pub fn relative(&self, dir: Direction, mul: i32) -> Self {
40        let (dx, dy, dz) = dir.normal(mul);
41        self.add(dx, dy, dz)
42    }
43
44}
45
46impl Default for BlockPos {
47    fn default() -> Self {
48        Self::nil()
49    }
50}
51
52macro_rules! impl_block_pos_relative_shortcut {
53    ($func_name:ident, $direction:ident) => {
54        impl BlockPos {
55            #[inline]
56            pub fn $func_name(&self, mul: i32) -> Self {
57                self.relative(Direction::$direction, mul)
58            }
59        }
60    };
61}
62
63impl_block_pos_relative_shortcut!(east, East);
64impl_block_pos_relative_shortcut!(west, West);
65impl_block_pos_relative_shortcut!(south, South);
66impl_block_pos_relative_shortcut!(north, North);
67impl_block_pos_relative_shortcut!(above, Up);
68impl_block_pos_relative_shortcut!(below, Down);
69
70
71/// This is a standard structure used to exchange block positions. Coordinates
72/// are 64-bits floating point numbers.
73#[derive(Debug, PartialEq, Clone)]
74pub struct EntityPos {
75    pub x: f64,
76    pub y: f64,
77    pub z: f64,
78}
79
80impl EntityPos {
81
82    #[inline]
83    pub fn new(x: f64, y: f64, z: f64) -> Self {
84        Self { x, y, z }
85    }
86
87    #[inline]
88    pub fn nil() -> Self {
89        Self::new(0.0, 0.0, 0.0)
90    }
91
92    #[inline]
93    pub fn into_array(&self) -> [f64; 3] {
94        [self.x, self.y, self.z]
95    }
96
97}
98
99impl Default for EntityPos {
100    fn default() -> Self {
101        Self::nil()
102    }
103}
104
105// Conversions //
106
107impl From<&'_ BlockPos> for EntityPos {
108    fn from(pos: &'_ BlockPos) -> Self {
109        Self::new(pos.x as f64, pos.y as f64, pos.z as f64)
110    }
111}
112
113impl From<&'_ EntityPos> for BlockPos {
114    fn from(pos: &'_ EntityPos) -> Self {
115        Self::new(pos.x.floor() as i32, pos.y.floor() as i32, pos.z.floor() as i32)
116    }
117}
118
119
120/// Cardinal direction used in-game.
121#[derive(Debug, Copy, Clone, Eq, PartialEq)]
122pub enum Direction {
123    East,  // +X
124    West,  // -X
125    South, // +Z
126    North, // -Z
127    Up,    // +Y
128    Down,  // -Y
129}
130
131impl Direction {
132
133    pub fn opposite(self) -> Self {
134        match self {
135            Self::East => Self::West,
136            Self::West => Self::East,
137            Self::South => Self::North,
138            Self::North => Self::South,
139            Self::Up => Self::Down,
140            Self::Down => Self::Up
141        }
142    }
143
144    pub fn axis(self) -> Axis {
145        match self {
146            Self::East | Self::West => Axis::X,
147            Self::South | Self::North => Axis::Z,
148            Self::Up | Self::Down => Axis::Y,
149        }
150    }
151
152    pub fn normal(self, mul: i32) -> (i32, i32, i32) {
153        match self {
154            Self::East => (mul, 0, 0),
155            Self::West => (-mul, 0, 0),
156            Self::South => (0, 0, mul),
157            Self::North => (0, 0, -mul),
158            Self::Up => (0, mul, 0),
159            Self::Down => (0, -mul, 0)
160        }
161    }
162
163}
164
165
166#[derive(Debug, Copy, Clone, Eq, PartialEq)]
167pub enum Axis {
168    X,
169    Y,
170    Z
171}
172
173impl Axis {
174
175    pub fn directions(self) -> (Direction, Direction) {
176        match self {
177            Self::X => (Direction::East, Direction::West),
178            Self::Y => (Direction::Up, Direction::Down),
179            Self::Z => (Direction::South, Direction::North)
180        }
181    }
182
183}