diff options
| author | mat <github@matdoes.dev> | 2022-05-14 14:12:57 -0500 |
|---|---|---|
| committer | mat <github@matdoes.dev> | 2022-05-14 14:12:57 -0500 |
| commit | 6d2fd8afbad44bbe88f701e1d67cc2f251246c07 (patch) | |
| tree | 3fa06efe4408c28db89aa6f115414d7a6995b1cc /azalea-world/src | |
| parent | 70271ede1982b618b5bb592da4adffabcdd76dac (diff) | |
| download | azalea-drasl-6d2fd8afbad44bbe88f701e1d67cc2f251246c07.tar.xz | |
start adding get_block_state
Diffstat (limited to 'azalea-world/src')
| -rw-r--r-- | azalea-world/src/bit_storage.rs | 16 | ||||
| -rw-r--r-- | azalea-world/src/lib.rs | 43 | ||||
| -rw-r--r-- | azalea-world/src/palette.rs | 30 |
3 files changed, 83 insertions, 6 deletions
diff --git a/azalea-world/src/bit_storage.rs b/azalea-world/src/bit_storage.rs index 3f810f40..f24a0514 100644 --- a/azalea-world/src/bit_storage.rs +++ b/azalea-world/src/bit_storage.rs @@ -103,6 +103,9 @@ impl BitStorage { /// Create a new BitStorage with the given number of bits per entry. /// `size` is the number of entries in the BitStorage. pub fn new(bits: usize, size: usize, data: Option<Vec<u64>>) -> Result<Self, BitStorageError> { + // vanilla has this assert but it's not always true for some reason?? + // assert!(bits >= 1 && bits <= 32); + if let Some(data) = &data { if data.len() == 0 { // TODO: make 0 bit storage actually work @@ -142,10 +145,12 @@ impl BitStorage { } pub fn cell_index(&self, index: u64) -> usize { - let first = self.divide_mul as u64; + // as unsigned wrap + let first = self.divide_mul as u32 as u64; let second = self.divide_add as u64; + dbg!(first, second, index); - (index * first + second >> 32 >> self.divide_shift) + (((index * first) + second) >> 32 >> self.divide_shift) .try_into() .unwrap() } @@ -157,7 +162,12 @@ impl BitStorage { // int var5 = (var1 - var2 * this.valuesPerLong) * this.bits; // return (int)(var3 >> var5 & this.mask); - assert!(index <= self.size - 1); + assert!( + index <= self.size - 1, + "Index {} out of bounds (max is {})", + index, + self.size - 1 + ); let cell_index = self.cell_index(index as u64); let cell = &self.data[cell_index as usize]; let bit_index = (index - cell_index * self.values_per_long as usize) * self.bits; diff --git a/azalea-world/src/lib.rs b/azalea-world/src/lib.rs index 4da2fb0f..aa99a470 100644 --- a/azalea-world/src/lib.rs +++ b/azalea-world/src/lib.rs @@ -1,7 +1,8 @@ mod bit_storage; mod palette; -use azalea_core::ChunkPos; +use crate::palette::PalettedContainerType; +use azalea_core::{BlockPos, ChunkPos, ChunkSectionBlockPos}; use azalea_protocol::mc_buf::{McBufReadable, McBufWritable}; pub use bit_storage::BitStorage; use palette::PalettedContainer; @@ -11,8 +12,6 @@ use std::{ sync::{Arc, Mutex}, }; -use crate::palette::PalettedContainerType; - #[cfg(test)] mod tests { #[test] @@ -54,6 +53,10 @@ impl World { pub fn update_view_center(&mut self, pos: &ChunkPos) { self.storage.view_center = *pos; } + + pub fn get_block_state(&self, pos: &BlockPos) -> Option<u32> { + self.storage.get_block_state(pos) + } } impl Index<&ChunkPos> for World { type Output = Option<Arc<Mutex<Chunk>>>; @@ -115,6 +118,15 @@ impl ChunkStorage { (chunk_pos.x - self.view_center.x).unsigned_abs() <= self.chunk_radius && (chunk_pos.z - self.view_center.z).unsigned_abs() <= self.chunk_radius } + + pub fn get_block_state(&self, pos: &BlockPos) -> Option<u32> { + let chunk_pos = ChunkPos::from(pos); + let chunk = &self[&chunk_pos]; + match chunk { + Some(chunk) => Some(chunk.lock().unwrap().get(pos)), + None => None, + } + } } impl Index<&ChunkPos> for ChunkStorage { @@ -150,6 +162,23 @@ impl Chunk { } Ok(Chunk { sections }) } + + pub fn section_index(&self, y: i32) -> u32 { + // TODO: check the build height and stuff, this code will be broken if the min build height is 0 + // (LevelHeightAccessor.getMinSection in vanilla code) + assert!(y >= 0); + (y as u32) / 16 + } + + pub fn get(&self, pos: &BlockPos) -> u32 { + let section_index = self.section_index(pos.y); + println!("section index: {}", section_index); + // TODO: make sure the section exists + let section = &self.sections[section_index as usize]; + let chunk_section_pos = ChunkSectionBlockPos::from(pos); + let block_state = section.get(chunk_section_pos); + block_state + } } impl McBufWritable for Chunk { @@ -194,3 +223,11 @@ impl McBufWritable for Section { Ok(()) } } + +impl Section { + // TODO: return a BlockState instead of a u32 + fn get(&self, pos: ChunkSectionBlockPos) -> u32 { + self.states + .get(pos.x as usize, pos.y as usize, pos.z as usize) + } +} diff --git a/azalea-world/src/palette.rs b/azalea-world/src/palette.rs index 55a33bde..6dc5e183 100644 --- a/azalea-world/src/palette.rs +++ b/azalea-world/src/palette.rs @@ -15,6 +15,7 @@ pub struct PalettedContainer { pub palette: Palette, /// Compacted list of indices pointing to entry IDs in the Palette. pub storage: BitStorage, + pub container_type: PalettedContainerType, } impl PalettedContainer { @@ -47,9 +48,29 @@ impl PalettedContainer { bits_per_entry, palette, storage, + container_type: *type_, }) } + + pub fn get_index(&self, x: usize, y: usize, z: usize) -> usize { + let size_bits = match self.container_type { + PalettedContainerType::BlockStates => 4, + PalettedContainerType::Biomes => 2, + }; + + (((y << size_bits) | z) << size_bits) | x + } + + pub fn get(&self, x: usize, y: usize, z: usize) -> u32 { + println!( + "get: {} {} {}, bits per entry: {}", + x, y, z, self.bits_per_entry + ); + let paletted_value = self.storage.get(self.get_index(x, y, z)); + self.palette.value_for(paletted_value as usize) + } } + impl McBufWritable for PalettedContainer { fn write_into(&self, buf: &mut impl Write) -> Result<(), std::io::Error> { buf.write_byte(self.bits_per_entry)?; @@ -91,6 +112,15 @@ impl Palette { _ => Palette::Global, }) } + + pub fn value_for(&self, value: usize) -> u32 { + match self { + Palette::SingleValue(v) => *v, + Palette::Linear(v) => v[value], + Palette::Hashmap(v) => v[value], + Palette::Global => value as u32, + } + } } impl McBufWritable for Palette { |
