mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-05 17:44:52 +01:00
world/section: add method to get block ID at coordinate
This commit is contained in:
parent
3cee4a4247
commit
b918ff6106
1 changed files with 69 additions and 5 deletions
|
@ -1,6 +1,7 @@
|
|||
use anyhow::{bail, Context, Result};
|
||||
|
||||
use super::de;
|
||||
use crate::{resource, types::*};
|
||||
|
||||
fn palette_bits(len: usize, min: u8, max: u8) -> Option<u8> {
|
||||
let mut bits = min;
|
||||
|
@ -15,7 +16,9 @@ fn palette_bits(len: usize, min: u8, max: u8) -> Option<u8> {
|
|||
Some(bits)
|
||||
}
|
||||
|
||||
pub trait Section {}
|
||||
pub trait Section {
|
||||
fn get_block_id(&self, coords: BlockCoords) -> Result<&str>;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PaletteSectionBiomes<'a> {
|
||||
|
@ -81,9 +84,48 @@ impl<'a> PaletteSection<'a> {
|
|||
aligned_blocks,
|
||||
})
|
||||
}
|
||||
|
||||
fn get_palette_index(&self, coords: BlockCoords) -> usize {
|
||||
let Some(block_states) = self.block_states else {
|
||||
return 0;
|
||||
};
|
||||
|
||||
let bits = self.bits as usize;
|
||||
let mask = (1 << bits) - 1;
|
||||
|
||||
let offset = coords.offset();
|
||||
|
||||
let shifted = if self.aligned_blocks {
|
||||
let blocks_per_word = 64 / bits;
|
||||
let (word, shift) = offset.div_rem(blocks_per_word);
|
||||
block_states[word] as u64 >> (shift * bits)
|
||||
} else {
|
||||
let bit_offset = offset * bits;
|
||||
let (word, bit_shift) = bit_offset.div_rem(64);
|
||||
|
||||
if bit_shift + bits <= 64 {
|
||||
block_states[word] as u64 >> bit_shift
|
||||
} else {
|
||||
let tmp = (block_states[word + 1] as u64 as u128) << 64
|
||||
| block_states[word] as u64 as u128;
|
||||
(tmp >> bit_shift) as u64
|
||||
}
|
||||
};
|
||||
|
||||
(shifted & mask) as usize
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Section for PaletteSection<'a> {}
|
||||
impl<'a> Section for PaletteSection<'a> {
|
||||
fn get_block_id(&self, coords: BlockCoords) -> Result<&str> {
|
||||
let index = self.get_palette_index(coords);
|
||||
let entry = self
|
||||
.palette
|
||||
.get(index)
|
||||
.context("Palette index out of bounds")?;
|
||||
Ok(&entry.name)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct OldSection<'a> {
|
||||
|
@ -93,9 +135,31 @@ pub struct OldSection<'a> {
|
|||
|
||||
impl<'a> OldSection<'a> {
|
||||
pub fn new(blocks: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray) -> Result<Self> {
|
||||
// TODO: Check lengths
|
||||
Ok(Self { blocks, data })
|
||||
const N: usize = BLOCKS_PER_CHUNK as usize;
|
||||
if blocks.len() != N * N * N {
|
||||
bail!("Invalid section block data");
|
||||
}
|
||||
if data.len() != N * N * N / 2 {
|
||||
bail!("Invalid section extra data");
|
||||
}
|
||||
|
||||
Ok(OldSection { blocks, data })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Section for OldSection<'a> {}
|
||||
impl<'a> Section for OldSection<'a> {
|
||||
fn get_block_id(&self, coords: BlockCoords) -> Result<&str> {
|
||||
let offset = coords.offset();
|
||||
let block = self.blocks[offset] as u8;
|
||||
|
||||
let (data_offset, data_nibble) = offset.div_rem(2);
|
||||
let data_byte = self.data[data_offset] as u8;
|
||||
let data = if data_nibble == 1 {
|
||||
data_byte >> 4
|
||||
} else {
|
||||
data_byte & 0xf
|
||||
};
|
||||
|
||||
Ok(resource::LEGACY_BLOCK_TYPES[block as usize][data as usize])
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue