diff options
| author | mat <git@matdoes.dev> | 2023-12-13 22:03:54 -0600 |
|---|---|---|
| committer | mat <git@matdoes.dev> | 2023-12-13 22:03:54 -0600 |
| commit | cc0717f45e14233a1002d1cb709aba298f89ef8c (patch) | |
| tree | ab15156f4dd997d6aff5fd192fdd4f8c3a3c3070 | |
| parent | 5b7ed4852c5b47a47a231832d418bad0d69fa563 (diff) | |
| download | azalea-drasl-cc0717f45e14233a1002d1cb709aba298f89ef8c.tar.xz | |
i didn't actually commit the code
| -rwxr-xr-x | azalea-core/src/position.rs | 39 | ||||
| -rwxr-xr-x | azalea-world/src/chunk_storage.rs | 41 |
2 files changed, 70 insertions, 10 deletions
diff --git a/azalea-core/src/position.rs b/azalea-core/src/position.rs index 196a70d5..4cdf3f18 100755 --- a/azalea-core/src/position.rs +++ b/azalea-core/src/position.rs @@ -213,7 +213,7 @@ impl BlockPos { /// Chunk coordinates are used to represent where a chunk is in the world. You /// can convert the x and z to block coordinates by multiplying them by 16. -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, McBuf)] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] pub struct ChunkPos { pub x: i32, pub z: i32, @@ -233,12 +233,38 @@ impl Add<ChunkPos> for ChunkPos { } } } + +// reading ChunkPos is done in reverse, so z first and then x +// ........ +// mojang why impl From<ChunkPos> for u64 { #[inline] fn from(pos: ChunkPos) -> Self { - ((pos.x as u64) << 32) | (pos.z as u64) + (pos.x as u64) | ((pos.z as u64) << 32) + } +} +impl From<u64> for ChunkPos { + #[inline] + fn from(pos: u64) -> Self { + ChunkPos { + x: (pos) as i32, + z: (pos >> 32) as i32, + } + } +} +impl McBufReadable for ChunkPos { + fn read_from(buf: &mut Cursor<&[u8]>) -> Result<Self, BufReadError> { + let long = u64::read_from(buf)?; + Ok(ChunkPos::from(long)) } } +impl McBufWritable for ChunkPos { + fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { + u64::from(*self).write_into(buf)?; + Ok(()) + } +} + impl Hash for ChunkPos { #[inline] fn hash<H: std::hash::Hasher>(&self, state: &mut H) { @@ -600,4 +626,13 @@ mod tests { ChunkSectionBlockPos::new(0, 4, 0) ); } + + #[test] + fn test_read_chunk_pos_from() { + let mut buf = Vec::new(); + ChunkPos::new(2, -1).write_into(&mut buf).unwrap(); + let mut buf = Cursor::new(&buf[..]); + let chunk_pos = ChunkPos::from(u64::read_from(&mut buf).unwrap()); + assert_eq!(chunk_pos, ChunkPos::new(2, -1)); + } } diff --git a/azalea-world/src/chunk_storage.rs b/azalea-world/src/chunk_storage.rs index 2e1c87c2..681f979b 100755 --- a/azalea-world/src/chunk_storage.rs +++ b/azalea-world/src/chunk_storage.rs @@ -123,18 +123,30 @@ impl PartialChunkStorage { self.view_center } + pub fn view_range(&self) -> u32 { + self.view_range + } + pub fn index_from_chunk_pos(&self, chunk_pos: &ChunkPos) -> usize { - (i32::rem_euclid(chunk_pos.x, self.view_range as i32) * (self.view_range as i32) - + i32::rem_euclid(chunk_pos.z, self.view_range as i32)) as usize + let view_range = self.view_range as i32; + + let x = i32::rem_euclid(chunk_pos.x, view_range) * view_range; + let z = i32::rem_euclid(chunk_pos.z, view_range); + (x + z) as usize } pub fn chunk_pos_from_index(&self, index: usize) -> ChunkPos { - let x = index as i32 % self.view_range as i32; - let z = index as i32 / self.view_range as i32; - ChunkPos::new( - x + self.view_center.x - self.chunk_radius as i32, - z + self.view_center.z - self.chunk_radius as i32, - ) + let view_range = self.view_range as i32; + + // find the base from the view center + let base_x = self.view_center.x.div_euclid(view_range) * view_range; + let base_z = self.view_center.z.div_euclid(view_range) * view_range; + + // add the offset from the base + let offset_x = index as i32 / view_range; + let offset_z = index as i32 % view_range; + + ChunkPos::new(base_x + offset_x, base_z + offset_z) } pub fn in_range(&self, chunk_pos: &ChunkPos) -> bool { @@ -207,6 +219,7 @@ impl PartialChunkStorage { } let index = self.index_from_chunk_pos(pos); + Some(&mut self.chunks[index]) } @@ -547,4 +560,16 @@ mod tests { .get_block_state(&BlockPos { x: 0, y: -65, z: 0 }) .is_none()); } + + #[test] + fn test_chunk_pos_from_index() { + let mut partial_chunk_storage = PartialChunkStorage::new(5); + partial_chunk_storage.update_view_center(ChunkPos::new(0, -1)); + assert_eq!( + partial_chunk_storage.chunk_pos_from_index( + partial_chunk_storage.index_from_chunk_pos(&ChunkPos::new(2, -1)) + ), + ChunkPos::new(2, -1), + ); + } } |
