world: store BlockTypes in section types

Prepare for sections returning BlockType data directly instead of block IDs.
This commit is contained in:
Matthias Schiffer 2023-03-01 23:14:57 +01:00
parent 89af4aaee2
commit f2ab424590
Signed by: neocturne
GPG key ID: 16EF3F64CB201D9C
3 changed files with 39 additions and 14 deletions

View file

@ -75,7 +75,7 @@ impl<'a> RegionProcessor<'a> {
/// Processes a single chunk /// Processes a single chunk
fn process_chunk(&self, data: world::de::Chunk) -> Result<Box<world::layer::BlockInfoArray>> { fn process_chunk(&self, data: world::de::Chunk) -> Result<Box<world::layer::BlockInfoArray>> {
let chunk = world::chunk::Chunk::new(&data)?; let chunk = world::chunk::Chunk::new(&data, &self.block_types)?;
world::layer::top_layer(&chunk, &self.block_types) world::layer::top_layer(&chunk, &self.block_types)
} }

View file

@ -9,7 +9,7 @@ use super::{
de, de,
section::{BiomesV18, Section, SectionV0, SectionV1_13}, section::{BiomesV18, Section, SectionV0, SectionV1_13},
}; };
use crate::types::*; use crate::{resource::BlockTypes, types::*};
/// Chunk data structure wrapping a [de::Chunk] for convenient access to /// Chunk data structure wrapping a [de::Chunk] for convenient access to
/// block and biome data /// block and biome data
@ -67,17 +67,23 @@ pub struct SectionIter<'a> {
impl<'a> Chunk<'a> { impl<'a> Chunk<'a> {
/// Creates a new [Chunk] from a deserialized [de::Chunk] /// Creates a new [Chunk] from a deserialized [de::Chunk]
pub fn new(data: &'a de::Chunk) -> Result<Self> { pub fn new(data: &'a de::Chunk, block_types: &'a BlockTypes) -> Result<Self> {
let data_version = data.data_version.unwrap_or_default(); let data_version = data.data_version.unwrap_or_default();
match &data.chunk { match &data.chunk {
de::ChunkVariants::V1_18 { sections } => Self::new_v1_18(data_version, sections), de::ChunkVariants::V1_18 { sections } => {
de::ChunkVariants::V0 { level } => Self::new_v0(data_version, level), Self::new_v1_18(data_version, sections, block_types)
}
de::ChunkVariants::V0 { level } => Self::new_v0(data_version, level, block_types),
} }
} }
/// [Chunk::new] implementation for Minecraft v1.18+ chunks /// [Chunk::new] implementation for Minecraft v1.18+ chunks
fn new_v1_18(data_version: u32, sections: &'a Vec<de::SectionV1_18>) -> Result<Self> { fn new_v1_18(
data_version: u32,
sections: &'a Vec<de::SectionV1_18>,
block_types: &'a BlockTypes,
) -> Result<Self> {
let mut section_map = BTreeMap::new(); let mut section_map = BTreeMap::new();
for section in sections { for section in sections {
@ -88,6 +94,7 @@ impl<'a> Chunk<'a> {
data_version, data_version,
section.block_states.data.as_ref(), section.block_states.data.as_ref(),
&section.block_states.palette, &section.block_states.palette,
block_types,
) )
.with_context(|| format!("Failed to load section at Y={}", section.y))?, .with_context(|| format!("Failed to load section at Y={}", section.y))?,
BiomesV18::new(section.biomes.data.as_ref(), &section.biomes.palette) BiomesV18::new(section.biomes.data.as_ref(), &section.biomes.palette)
@ -102,7 +109,11 @@ impl<'a> Chunk<'a> {
} }
/// [Chunk::new] implementation for all pre-1.18 chunk variants /// [Chunk::new] implementation for all pre-1.18 chunk variants
fn new_v0(data_version: u32, level: &'a de::LevelV0) -> Result<Self> { fn new_v0(
data_version: u32,
level: &'a de::LevelV0,
block_types: &'a BlockTypes,
) -> Result<Self> {
let mut section_map_v1_13 = BTreeMap::new(); let mut section_map_v1_13 = BTreeMap::new();
let mut section_map_v0 = BTreeMap::new(); let mut section_map_v0 = BTreeMap::new();
@ -114,15 +125,14 @@ impl<'a> Chunk<'a> {
} => { } => {
section_map_v1_13.insert( section_map_v1_13.insert(
SectionY(section.y.into()), SectionY(section.y.into()),
SectionV1_13::new(data_version, Some(block_states), palette).with_context( SectionV1_13::new(data_version, Some(block_states), palette, block_types)
|| format!("Failed to load section at Y={}", section.y), .with_context(|| format!("Failed to load section at Y={}", section.y))?,
)?,
); );
} }
de::SectionV0Variants::V0 { blocks, data } => { de::SectionV0Variants::V0 { blocks, data } => {
section_map_v0.insert( section_map_v0.insert(
SectionY(section.y.into()), SectionY(section.y.into()),
SectionV0::new(blocks, data).with_context(|| { SectionV0::new(blocks, data, block_types).with_context(|| {
format!("Failed to load section at Y={}", section.y) format!("Failed to load section at Y={}", section.y)
})?, })?,
); );

View file

@ -2,7 +2,10 @@ use anyhow::{bail, Context, Result};
use num_integer::div_rem; use num_integer::div_rem;
use super::de; use super::de;
use crate::{resource, types::*}; use crate::{
resource::{self, BlockTypes},
types::*,
};
/// Determine the number of bits required for indexing into a palette of a given length /// Determine the number of bits required for indexing into a palette of a given length
/// ///
@ -65,6 +68,7 @@ impl<'a> BiomesV18<'a> {
pub struct SectionV1_13<'a> { pub struct SectionV1_13<'a> {
block_states: Option<&'a fastnbt::LongArray>, block_states: Option<&'a fastnbt::LongArray>,
palette: &'a Vec<de::BlockStatePaletteEntry>, palette: &'a Vec<de::BlockStatePaletteEntry>,
_block_types: &'a BlockTypes,
bits: u8, bits: u8,
aligned_blocks: bool, aligned_blocks: bool,
} }
@ -75,6 +79,7 @@ impl<'a> SectionV1_13<'a> {
data_version: u32, data_version: u32,
block_states: Option<&'a fastnbt::LongArray>, block_states: Option<&'a fastnbt::LongArray>,
palette: &'a Vec<de::BlockStatePaletteEntry>, palette: &'a Vec<de::BlockStatePaletteEntry>,
block_types: &'a BlockTypes,
) -> Result<Self> { ) -> Result<Self> {
let aligned_blocks = data_version >= 2529; let aligned_blocks = data_version >= 2529;
@ -95,6 +100,7 @@ impl<'a> SectionV1_13<'a> {
Ok(Self { Ok(Self {
block_states, block_states,
palette, palette,
_block_types: block_types,
bits, bits,
aligned_blocks, aligned_blocks,
}) })
@ -146,11 +152,16 @@ impl<'a> Section for SectionV1_13<'a> {
pub struct SectionV0<'a> { pub struct SectionV0<'a> {
blocks: &'a fastnbt::ByteArray, blocks: &'a fastnbt::ByteArray,
data: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray,
_block_types: &'a BlockTypes,
} }
impl<'a> SectionV0<'a> { impl<'a> SectionV0<'a> {
/// Constructs a new [SectionV0] from deserialized data structures /// Constructs a new [SectionV0] from deserialized data structures
pub fn new(blocks: &'a fastnbt::ByteArray, data: &'a fastnbt::ByteArray) -> Result<Self> { pub fn new(
blocks: &'a fastnbt::ByteArray,
data: &'a fastnbt::ByteArray,
block_types: &'a BlockTypes,
) -> Result<Self> {
use BLOCKS_PER_CHUNK as N; use BLOCKS_PER_CHUNK as N;
if blocks.len() != N * N * N { if blocks.len() != N * N * N {
@ -160,7 +171,11 @@ impl<'a> SectionV0<'a> {
bail!("Invalid section extra data"); bail!("Invalid section extra data");
} }
Ok(SectionV0 { blocks, data }) Ok(SectionV0 {
blocks,
data,
_block_types: block_types,
})
} }
} }