use azalea_core::position::ChunkPos;
#[derive(Debug, Clone)]
pub struct Chunk {
pub pos: ChunkPos,
pub sections: Vec<ChunkSection>,
pub raw_data: Vec<u8>,
}
impl Chunk {
pub fn new(pos: ChunkPos, raw_data: Vec<u8>) -> Self {
Self {
pos,
sections: vec![ChunkSection::empty(); 24],
raw_data,
}
}
pub fn get_block(&self, x: usize, y: usize, z: usize) -> Option<u32> {
if x >= 16 || y >= 384 || z >= 16 {
return None;
}
let section_index = y / 16;
let section_y = y % 16;
self.sections.get(section_index)?.get_block(x, section_y, z)
}
pub fn set_block(&mut self, x: usize, y: usize, z: usize, block_state: u32) {
if x >= 16 || y >= 384 || z >= 16 {
return;
}
let section_index = y / 16;
let section_y = y % 16;
if let Some(section) = self.sections.get_mut(section_index) {
section.set_block(x, section_y, z, block_state);
}
}
}
#[derive(Debug, Clone)]
pub struct ChunkSection {
pub palette: Vec<u32>,
pub blocks: Vec<u16>,
pub non_air_blocks: u16,
}
impl ChunkSection {
pub fn empty() -> Self {
Self {
palette: vec![0],
blocks: vec![0; 4096],
non_air_blocks: 0,
}
}
pub fn get_block(&self, x: usize, y: usize, z: usize) -> Option<u32> {
if x >= 16 || y >= 16 || z >= 16 {
return None;
}
let index = (y * 16 * 16) + (z * 16) + x;
let palette_index = *self.blocks.get(index)? as usize;
self.palette.get(palette_index).copied()
}
pub fn set_block(&mut self, x: usize, y: usize, z: usize, block_state: u32) {
if x >= 16 || y >= 16 || z >= 16 {
return;
}
let index = (y * 16 * 16) + (z * 16) + x;
let palette_index = if let Some(idx) = self.palette.iter().position(|&b| b == block_state) {
idx
} else {
self.palette.push(block_state);
self.palette.len() - 1
};
let old_state = self.blocks[index];
if old_state == 0 && block_state != 0 {
self.non_air_blocks += 1;
} else if old_state != 0 && block_state == 0 {
self.non_air_blocks = self.non_air_blocks.saturating_sub(1);
}
self.blocks[index] = palette_index as u16;
}
}