chunkedge_protocol/
chunk_pos.rs

1use chunkedge_binary::{Decode, Encode};
2use chunkedge_math::DVec3;
3
4use crate::block_pos::BlockPos;
5use crate::chunk_section_pos::ChunkSectionPos;
6use crate::BiomePos;
7
8/// The X and Z position of a chunk.
9#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default, Hash, Debug, Encode, Decode)]
10pub struct ChunkPos {
11    /// The X position of the chunk.
12    pub x: i32,
13    /// The Z position of the chunk.
14    pub z: i32,
15}
16
17impl ChunkPos {
18    /// Constructs a new chunk position.
19    pub const fn new(x: i32, z: i32) -> Self {
20        Self { x, z }
21    }
22
23    pub const fn distance_squared(self, other: Self) -> u64 {
24        let diff_x = other.x as i64 - self.x as i64;
25        let diff_z = other.z as i64 - self.z as i64;
26
27        (diff_x * diff_x + diff_z * diff_z) as u64
28    }
29}
30
31impl From<BlockPos> for ChunkPos {
32    fn from(pos: BlockPos) -> Self {
33        Self {
34            x: pos.x.div_euclid(16),
35            z: pos.z.div_euclid(16),
36        }
37    }
38}
39
40impl From<ChunkSectionPos> for ChunkPos {
41    fn from(pos: ChunkSectionPos) -> Self {
42        Self { x: pos.x, z: pos.z }
43    }
44}
45
46impl From<BiomePos> for ChunkPos {
47    fn from(pos: BiomePos) -> Self {
48        Self {
49            x: pos.x.div_euclid(4),
50            z: pos.z.div_euclid(4),
51        }
52    }
53}
54
55impl From<DVec3> for ChunkPos {
56    fn from(pos: DVec3) -> Self {
57        Self {
58            x: (pos.x / 16.0).floor() as i32,
59            z: (pos.z / 16.0).floor() as i32,
60        }
61    }
62}
63
64impl From<(i32, i32)> for ChunkPos {
65    fn from((x, z): (i32, i32)) -> Self {
66        Self { x, z }
67    }
68}
69
70impl From<ChunkPos> for (i32, i32) {
71    fn from(pos: ChunkPos) -> Self {
72        (pos.x, pos.z)
73    }
74}
75
76impl From<[i32; 2]> for ChunkPos {
77    fn from([x, z]: [i32; 2]) -> Self {
78        Self { x, z }
79    }
80}
81
82impl From<ChunkPos> for [i32; 2] {
83    fn from(pos: ChunkPos) -> Self {
84        [pos.x, pos.z]
85    }
86}
87
88#[cfg(test)]
89mod tests {
90    use super::*;
91
92    #[test]
93    fn chunk_pos_round_trip_conv() {
94        let p = ChunkPos::new(rand::random(), rand::random());
95
96        assert_eq!(ChunkPos::from(<(i32, i32)>::from(p)), p);
97        assert_eq!(ChunkPos::from(<[i32; 2]>::from(p)), p);
98    }
99}