aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormat <git@matdoes.dev>2023-12-13 22:03:54 -0600
committermat <git@matdoes.dev>2023-12-13 22:03:54 -0600
commitcc0717f45e14233a1002d1cb709aba298f89ef8c (patch)
treeab15156f4dd997d6aff5fd192fdd4f8c3a3c3070
parent5b7ed4852c5b47a47a231832d418bad0d69fa563 (diff)
downloadazalea-drasl-cc0717f45e14233a1002d1cb709aba298f89ef8c.tar.xz
i didn't actually commit the code
-rwxr-xr-xazalea-core/src/position.rs39
-rwxr-xr-xazalea-world/src/chunk_storage.rs41
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),
+ );
+ }
}