fastanvil 0.32.0

Minecraft Anvil library
Documentation
use crate::{complete, Chunk, HeightMode, JavaChunk};

const ETHO_OLD_HEIGHTS: &[u8] = include_bytes!("../../resources/etho-old-heightmaps.chunk");
const ETHO_MAX_HEIGHTS: &[u8] = include_bytes!("../../resources/etho-max-heights.chunk");
const ETHO_OLD_IN_NEW: &[u8] = include_bytes!("../../resources/etho-old-in-new.chunk");
const ETHO_OLD_IN_NEW2: &[u8] = include_bytes!("../../resources/etho-old-in-new2.chunk");
const ETHO: &[u8] = include_bytes!("../../resources/etho.chunk");
const ETHO_EMPTY: &[u8] = include_bytes!("../../resources/etho-empty.chunk");
const ETHO_EMPTY_SECTIONS: &[u8] = include_bytes!("../../resources/etho-end-r.-6.-1.c.7.25.nbt");

fn extract_heights(chunk: &mut dyn Chunk) -> [isize; 256] {
    let mut heights = [0; 256];
    for z in 0..16 {
        for x in 0..16 {
            heights[z * 16 + x] = chunk.surface_height(x, z, HeightMode::Calculate);
        }
    }
    heights
}

#[test]
fn etho_old_heightmap() {
    // Based on old heightmap data found in Etho's LP episode 550 world
    // download. r.1.0.mca, chunk with index x=7, z=8.
    let mut chunk = JavaChunk::from_bytes(ETHO_OLD_HEIGHTS).unwrap();

    let expected_heights = [
        64, 64, 65, 64, 65, 64, 64, 64, 64, 63, 63, 63, 63, 63, 63, 63, 66, 66, 64, 64, 64, 65, 65,
        64, 64, 64, 63, 63, 63, 64, 63, 63, 65, 65, 65, 65, 66, 65, 64, 64, 64, 64, 63, 63, 63, 63,
        63, 63, 66, 66, 67, 65, 66, 65, 65, 65, 64, 64, 63, 63, 63, 63, 63, 63, 66, 66, 66, 66, 66,
        66, 66, 65, 65, 64, 64, 63, 63, 63, 63, 63, 66, 67, 66, 66, 67, 66, 66, 65, 65, 64, 64, 63,
        63, 63, 63, 63, 66, 66, 66, 66, 66, 66, 66, 65, 65, 64, 64, 63, 63, 63, 63, 63, 66, 66, 66,
        66, 66, 66, 66, 66, 65, 64, 64, 63, 63, 63, 63, 63, 66, 66, 66, 66, 66, 66, 66, 66, 66, 64,
        64, 63, 63, 63, 63, 63, 66, 66, 66, 66, 66, 67, 66, 66, 66, 64, 64, 63, 63, 63, 63, 63, 66,
        66, 66, 66, 66, 66, 66, 66, 66, 64, 64, 63, 63, 63, 63, 63, 66, 66, 66, 66, 66, 66, 66, 66,
        66, 65, 64, 63, 63, 63, 63, 63, 66, 66, 66, 66, 66, 66, 66, 66, 66, 65, 64, 64, 63, 63, 63,
        63, 66, 66, 66, 66, 66, 66, 66, 66, 66, 65, 64, 64, 64, 63, 63, 63, 66, 66, 66, 66, 66, 66,
        66, 66, 66, 66, 65, 65, 64, 64, 63, 63, 67, 67, 67, 67, 67, 67, 67, 66, 66, 66, 66, 66, 66,
        65, 64, 63,
    ];

    assert_eq!(expected_heights, extract_heights(&mut chunk));
}

#[test]
fn etho_max_heights() {
    // Based on Etho's LP episode 550 world download. r.0.3.mca, chunk with
    // index x=24, z=6.
    let mut chunk = JavaChunk::from_bytes(ETHO_MAX_HEIGHTS).unwrap();

    let expected_heights = [
        251, 252, 253, 252, 252, 252, 252, 252, 252, 252, 252, 252, 251, 251, 251, 251, 251, 252,
        253, 252, 252, 252, 252, 252, 252, 252, 252, 252, 251, 251, 251, 251, 251, 251, 252, 253,
        253, 253, 253, 252, 253, 253, 252, 252, 252, 251, 251, 251, 252, 252, 251, 252, 252, 252,
        252, 252, 252, 252, 252, 252, 252, 251, 252, 251, 251, 252, 252, 252, 252, 251, 252, 252,
        252, 252, 252, 252, 252, 252, 251, 252, 251, 251, 251, 251, 252, 251, 252, 252, 252, 252,
        252, 252, 252, 252, 251, 252, 251, 251, 252, 252, 252, 251, 252, 252, 252, 253, 253, 253,
        252, 252, 251, 251, 251, 252, 251, 252, 252, 251, 253, 253, 252, 252, 253, 252, 252, 252,
        252, 251, 252, 251, 252, 251, 252, 251, 253, 252, 252, 252, 252, 252, 252, 252, 252, 252,
        251, 252, 251, 252, 252, 251, 251, 253, 252, 252, 252, 252, 253, 252, 252, 252, 251, 252,
        251, 251, 251, 251, 251, 252, 252, 252, 252, 252, 252, 252, 251, 251, 251, 251, 251, 251,
        251, 252, 251, 251, 252, 252, 252, 251, 251, 251, 251, 251, 252, 252, 251, 251, 251, 251,
        251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 251,
        251, 251, 251, 251, 251, 251, 251, 251, 251, 251, 252, 251, 251, 251, 251, 252, 251, 251,
        251, 251, 251, 251, 256, 251, 251, 251, 251, 252, 251, 251, 251, 252, 251, 251, 251, 251,
        252, 256, 256, 256,
    ];
    assert_eq!(expected_heights, extract_heights(&mut chunk));
}

#[test]
fn etho_old_in_new() {
    // Based Etho's LP episode 550 world download. r.-1.-1.mca, chunk with index
    // x=17, z=22.
    let mut chunk = JavaChunk::from_bytes(ETHO_OLD_IN_NEW).unwrap();
    let expected_heights = [
        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65,
        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
        64, 64, 65, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
        64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
        64, 64, 64,
    ];
    assert_eq!(expected_heights, extract_heights(&mut chunk));
}

#[test]
fn etho_old_in_new_with_rogue_bits() {
    // Based Etho's LP episode 550 world download. r.0.0.mca, chunk with index
    // x=16, z=21.
    let mut chunk = JavaChunk::from_bytes(ETHO_OLD_IN_NEW2).unwrap();
    let expected_heights = [
        64, 64, 65, 65, 65, 64, 64, 64, 63, 63, 67, 67, 68, 68, 69, 69, 64, 64, 64, 65, 65, 65, 65,
        64, 63, 63, 67, 67, 68, 68, 69, 69, 64, 64, 64, 65, 65, 65, 65, 66, 63, 63, 67, 67, 68, 68,
        69, 69, 64, 64, 64, 65, 65, 65, 65, 66, 66, 63, 67, 67, 68, 68, 69, 69, 63, 64, 64, 64, 65,
        65, 65, 66, 66, 66, 67, 67, 68, 68, 69, 69, 63, 64, 64, 64, 65, 65, 66, 66, 66, 66, 67, 67,
        68, 68, 69, 69, 63, 64, 64, 65, 65, 65, 66, 66, 66, 67, 67, 67, 68, 68, 69, 69, 63, 67, 68,
        68, 68, 67, 66, 66, 66, 67, 67, 68, 68, 68, 69, 69, 63, 68, 68, 70, 68, 68, 66, 66, 66, 67,
        67, 68, 68, 68, 69, 69, 63, 68, 70, 70, 70, 68, 66, 66, 67, 67, 67, 68, 68, 69, 69, 69, 63,
        68, 68, 70, 69, 68, 66, 66, 67, 67, 67, 68, 68, 69, 69, 69, 63, 68, 68, 68, 68, 68, 66, 66,
        67, 67, 68, 68, 68, 69, 69, 69, 63, 64, 64, 64, 65, 66, 66, 66, 67, 67, 68, 68, 69, 69, 69,
        69, 63, 64, 64, 65, 65, 66, 66, 66, 67, 67, 68, 68, 69, 69, 69, 69, 63, 64, 64, 65, 65, 66,
        66, 67, 67, 67, 68, 68, 69, 69, 69, 70, 64, 64, 64, 65, 66, 66, 66, 67, 67, 68, 68, 69, 69,
        69, 69, 70,
    ];
    assert_eq!(expected_heights, extract_heights(&mut chunk));
}

#[test]
fn etho() {
    // Based Etho's LP episode 550 world download. r.-1.-1.mca, chunk with index
    // x=27. z=0.
    let mut chunk = JavaChunk::from_bytes(ETHO).unwrap();

    let expected_heights = [
        63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
        63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
        63, 63, 63, 63, 63, 63, 64, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
        63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
        63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
        63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
        63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
        63, 63, 63, 63, 63, 63, 63, 65, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
        63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
        63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
        63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63,
        63, 63, 63,
    ];
    assert_eq!(expected_heights, extract_heights(&mut chunk));
}

#[test]
fn etho_empty() {
    // Based Etho's LP episode 550 world download. r.-1.-1.mca, chunk with index
    // x=27. z=0.
    let mut chunk = JavaChunk::from_bytes(ETHO_EMPTY).unwrap();

    let expected_heights = [
        75, 76, 76, 76, 75, 75, 67, 67, 66, 66, 66, 66, 66, 66, 66, 66, 75, 75, 75, 75, 75, 67, 67,
        67, 65, 66, 66, 66, 66, 66, 66, 66, 68, 68, 68, 67, 67, 67, 67, 67, 65, 66, 66, 66, 66, 66,
        66, 66, 68, 68, 67, 67, 67, 67, 67, 67, 65, 66, 66, 66, 66, 66, 66, 66, 68, 67, 67, 67, 67,
        69, 69, 69, 68, 68, 66, 66, 66, 66, 66, 66, 68, 67, 67, 67, 69, 69, 72, 72, 71, 68, 68, 66,
        75, 66, 66, 66, 68, 67, 67, 67, 69, 72, 72, 75, 71, 71, 68, 75, 76, 75, 66, 66, 68, 67, 67,
        67, 69, 72, 75, 75, 74, 71, 68, 65, 75, 65, 66, 66, 68, 68, 67, 67, 69, 72, 72, 75, 71, 71,
        68, 65, 65, 65, 65, 65, 68, 68, 67, 67, 69, 69, 72, 72, 73, 73, 73, 65, 65, 65, 65, 66, 68,
        67, 67, 67, 67, 69, 69, 74, 73, 74, 73, 73, 65, 65, 65, 66, 68, 67, 67, 67, 67, 67, 67, 74,
        74, 75, 74, 73, 65, 65, 65, 66, 68, 67, 67, 67, 67, 67, 67, 74, 73, 74, 73, 73, 65, 65, 65,
        66, 68, 68, 67, 67, 67, 67, 67, 67, 73, 73, 73, 65, 64, 65, 65, 65, 68, 68, 68, 67, 67, 67,
        67, 66, 65, 65, 65, 64, 64, 64, 64, 66, 68, 68, 68, 68, 67, 67, 67, 66, 65, 65, 64, 64, 64,
        64, 64, 66,
    ];
    let heights = extract_heights(&mut chunk);

    assert_eq!(expected_heights, heights);
}

#[test]
fn etho_end_empty_sections() {
    // This chunk has no sections, but does have biomes specified. This caused a
    // panic in the biome selction code due to y_range being 0..0.
    let chunk = JavaChunk::from_bytes(ETHO_EMPTY_SECTIONS).unwrap();
    assert_eq!(0..0, chunk.y_range());
    assert_eq!(None, chunk.biome(0, 0, 0));
}

#[test]
fn issue99() {
    let ch = include_bytes!("../../resources/issue99-chunk.nbt");
    let ch = complete::Chunk::from_bytes(ch).unwrap();
    for chunk_x in 0..16 {
        for chunk_z in 0..16 {
            for chunk_y in ch.y_range() {
                let _block = ch.block(chunk_x, chunk_y, chunk_z);
            }
        }
    }
}